forked from facebook/hermes
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a rudimentary implementation to CacheNewObject
Summary: Add a first-attempt, fairly conservative set of rules to the CacheNewObject optimization pass. If a function's first uses of `this` are as the target objects in property stores using literal keys function, and they occur in a sequence in which earlier users dominate later ones, and there's no `try` surrounding them, we can add the CacheNewObject instruction. Otherwise, we bail. The optimization only applies if there are MIN_PROPERTIES_FOR_CACHE writes to literal `this` properties in a row. Reviewed By: neildhar Differential Revision: D40532426 fbshipit-source-id: 5c1ad5748f71528ecedcab3ea621c0d9daf5be62
- Loading branch information
1 parent
7bee3d9
commit 3149ba9
Showing
5 changed files
with
495 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
// RUN: %hermesc -O -dump-bytecode %s | %FileCheckOrRegen --match-full-lines %s | ||
|
||
function simple(x, y) { | ||
// Check that CacheNewObject is used and refers to the shape table entry. | ||
this.x = x; | ||
this.y = y; | ||
} | ||
|
||
// Auto-generated content below. Please do not modify manually. | ||
|
||
// CHECK:Bytecode File Information: | ||
// CHECK-NEXT: Bytecode version number: {{.*}} | ||
// CHECK-NEXT: Source hash: {{.*}} | ||
// CHECK-NEXT: Function count: 2 | ||
// CHECK-NEXT: String count: 4 | ||
// CHECK-NEXT: BigInt count: 0 | ||
// CHECK-NEXT: String Kind Entry count: 2 | ||
// CHECK-NEXT: RegExp count: 0 | ||
// CHECK-NEXT: Segment ID: 0 | ||
// CHECK-NEXT: CommonJS module count: 0 | ||
// CHECK-NEXT: CommonJS module count (static): 0 | ||
// CHECK-NEXT: Function source count: 0 | ||
// CHECK-NEXT: Bytecode options: | ||
// CHECK-NEXT: staticBuiltins: 0 | ||
// CHECK-NEXT: cjsModulesStaticallyResolved: 0 | ||
|
||
// CHECK:Global String Table: | ||
// CHECK-NEXT:s0[ASCII, 0..5]: global | ||
// CHECK-NEXT:i1[ASCII, 6..11] #147A1A16: simple | ||
// CHECK-NEXT:i2[ASCII, 12..12] #0001E7F9: x | ||
// CHECK-NEXT:i3[ASCII, 13..13] #0001E3E8: y | ||
|
||
// CHECK:Object Key Buffer: | ||
// CHECK-NEXT:[String 2] | ||
// CHECK-NEXT:[String 3] | ||
// CHECK-NEXT:Object Shape Table: | ||
// CHECK-NEXT:0[0, 2] | ||
// CHECK-NEXT:Function<global>(1 params, 3 registers, 0 numbers, 1 non-pointers): | ||
// CHECK-NEXT:Offset in debug table: source 0x0000, lexical 0x0000 | ||
// CHECK-NEXT: DeclareGlobalVar "simple" | ||
// CHECK-NEXT: CreateTopLevelEnvironment r1, 0 | ||
// CHECK-NEXT: CreateClosure r2, r1, Function<simple> | ||
// CHECK-NEXT: GetGlobalObject r1 | ||
// CHECK-NEXT: PutByIdLoose r1, r2, 1, "simple" | ||
// CHECK-NEXT: LoadConstUndefined r0 | ||
// CHECK-NEXT: Ret r0 | ||
|
||
// CHECK:Function<simple>(3 params, 3 registers, 0 numbers, 1 non-pointers): | ||
// CHECK-NEXT:Offset in debug table: source 0x000a, lexical 0x0000 | ||
// CHECK-NEXT: LoadThisNS r2 | ||
// CHECK-NEXT: GetNewTarget r1 | ||
// CHECK-NEXT: CacheNewObject r2, 0 | ||
// CHECK-NEXT: LoadParam r1, 1 | ||
// CHECK-NEXT: PutByIdLoose r2, r1, 1, "x" | ||
// CHECK-NEXT: LoadParam r1, 2 | ||
// CHECK-NEXT: PutByIdLoose r2, r1, 2, "y" | ||
// CHECK-NEXT: LoadConstUndefined r0 | ||
// CHECK-NEXT: Ret r0 | ||
|
||
// CHECK:Debug filename table: | ||
// CHECK-NEXT: 0: {{.*}}cache-new-object.js | ||
|
||
// CHECK:Debug file table: | ||
// CHECK-NEXT: source table offset 0x0000: filename id 0 | ||
|
||
// CHECK:Debug source table: | ||
// CHECK-NEXT: 0x0000 function idx 0, starts at line 10 col 1 | ||
// CHECK-NEXT: bc 0: line 10 col 1 | ||
// CHECK-NEXT: bc 18: line 10 col 1 | ||
// CHECK-NEXT: 0x000a function idx 1, starts at line 10 col 1 | ||
// CHECK-NEXT: bc 13: line 12 col 10 | ||
// CHECK-NEXT: bc 22: line 13 col 10 | ||
// CHECK-NEXT: 0x0014 end of debug source table |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
// RUN: %hermesc -fno-inline -dump-ir %s -O | %FileCheckOrRegen --match-full-lines %s | ||
|
||
function main() { | ||
|
||
// Make sure allCallsitesKnownInStrictMode is true. | ||
function simple(x, y) { | ||
this.x = x; | ||
this.y = y; | ||
} | ||
|
||
return new simple(1, 2); | ||
|
||
} | ||
|
||
// Auto-generated content below. Please do not modify manually. | ||
|
||
// CHECK:scope %VS0 [] | ||
|
||
// CHECK:function global(): undefined | ||
// CHECK-NEXT:%BB0: | ||
// CHECK-NEXT: %0 = CreateScopeInst (:environment) %VS0: any, empty: any | ||
// CHECK-NEXT: DeclareGlobalVarInst "main": string | ||
// CHECK-NEXT: %2 = CreateFunctionInst (:object) %0: environment, %main(): functionCode | ||
// CHECK-NEXT: StorePropertyLooseInst %2: object, globalObject: object, "main": string | ||
// CHECK-NEXT: ReturnInst undefined: undefined | ||
// CHECK-NEXT:function_end | ||
|
||
// CHECK:function main(): object | ||
// CHECK-NEXT:%BB0: | ||
// CHECK-NEXT: %0 = GetParentScopeInst (:environment) %VS0: any, %parentScope: environment | ||
// CHECK-NEXT: %1 = CreateFunctionInst (:object) %0: environment, %simple(): functionCode | ||
// CHECK-NEXT: %2 = CreateThisInst (:undefined|object) %1: object, empty: any | ||
// CHECK-NEXT: %3 = CallInst (:undefined) %1: object, %simple(): functionCode, true: boolean, empty: any, undefined: undefined, %2: undefined|object, 1: number, 2: number | ||
// CHECK-NEXT: %4 = GetConstructedObjectInst (:object) %2: undefined|object, undefined: undefined | ||
// CHECK-NEXT: ReturnInst %4: object | ||
// CHECK-NEXT:function_end | ||
|
||
// CHECK:function simple(x: any, y: any): undefined [allCallsitesKnownInStrictMode] | ||
// CHECK-NEXT:%BB0: | ||
// CHECK-NEXT: %0 = LoadParamInst (:any) %<this>: any | ||
// CHECK-NEXT: %1 = CoerceThisNSInst (:object) %0: any | ||
// CHECK-NEXT: %2 = GetNewTargetInst (:undefined|object) %new.target: undefined|object | ||
// CHECK-NEXT: CacheNewObjectInst %1: object, %2: undefined|object, "x": string, "y": string | ||
// CHECK-NEXT: %4 = LoadParamInst (:any) %x: any | ||
// CHECK-NEXT: %5 = LoadParamInst (:any) %y: any | ||
// CHECK-NEXT: StorePropertyLooseInst %4: any, %1: object, "x": string | ||
// CHECK-NEXT: StorePropertyLooseInst %5: any, %1: object, "y": string | ||
// CHECK-NEXT: ReturnInst undefined: undefined | ||
// CHECK-NEXT:function_end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
// RUN: %hermesc -dump-ir %s -O | %FileCheck --match-full-lines %s | ||
|
||
// A variety of different functions which don't trigger CacheNewObjectInst | ||
// to be emitted. | ||
|
||
function cond(x, y) { | ||
if (y) | ||
this.y = y; | ||
this.x = x; | ||
} | ||
|
||
function assignProp(x, y) { | ||
x[this] = y; | ||
} | ||
|
||
function assignNotLit(x, y) { | ||
this[x] = x; | ||
} | ||
|
||
function usesThis(x, y) { | ||
this.x = x; | ||
this.y = this.z; | ||
} | ||
|
||
function noUses(x, y) { | ||
print(x); | ||
} | ||
|
||
function callArg(x, y) { | ||
print(this); | ||
} | ||
|
||
// CHECK-NOT: %{{.*}} CacheNewObjectInst {{.*}} |
Oops, something went wrong.