Commit ec8700c4 authored by Creddy's avatar Creddy Committed by Commit Bot

[interpreter][runtime] Avoid AllocationSites for oneshot code

No need to create allocation site for literals in oneshot code since
they are executed only once. The interpreter emits a runtime call to
CreateObjectLiteralWithoutAllocationSite for creating literals in
oneshot code instead.

Change-Id: I224b3a30f10361cfe9ff63129b36da8230c5e403
Reviewed-on: https://chromium-review.googlesource.com/1163615
Commit-Queue: Chandan Reddy <chandanreddy@google.com>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55050}
parent b321c95b
...@@ -312,6 +312,7 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) { ...@@ -312,6 +312,7 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) {
/* Literals */ \ /* Literals */ \
V(CreateArrayLiteral) \ V(CreateArrayLiteral) \
V(CreateObjectLiteral) \ V(CreateObjectLiteral) \
V(CreateObjectLiteralWithoutAllocationSite) \
V(CreateRegExpLiteral) \ V(CreateRegExpLiteral) \
/* Called from builtins */ \ /* Called from builtins */ \
V(AllocateInNewSpace) \ V(AllocateInNewSpace) \
......
...@@ -316,7 +316,7 @@ DEFINE_BOOL(optimize_for_size, false, ...@@ -316,7 +316,7 @@ DEFINE_BOOL(optimize_for_size, false,
"speed") "speed")
// Flag for one shot optimiztions. // Flag for one shot optimiztions.
DEFINE_BOOL(enable_one_shot_optimization, true, DEFINE_BOOL(enable_one_shot_optimization, false,
"Enable size optimizations for the code that will " "Enable size optimizations for the code that will "
"only be executed once") "only be executed once")
......
...@@ -2105,6 +2105,27 @@ void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { ...@@ -2105,6 +2105,27 @@ void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
expr->flags()); expr->flags());
} }
void BytecodeGenerator::BuildCreateObjectLiteral(Register literal,
uint8_t flags, size_t entry) {
if (ShouldOptimizeAsOneShot()) {
RegisterList args = register_allocator()->NewRegisterList(2);
builder()
->LoadConstantPoolEntry(entry)
.StoreAccumulatorInRegister(args[0])
.LoadLiteral(Smi::FromInt(flags))
.StoreAccumulatorInRegister(args[1])
.CallRuntime(Runtime::kCreateObjectLiteralWithoutAllocationSite, args)
.StoreAccumulatorInRegister(literal);
} else {
// TODO(cbruni): Directly generate runtime call for literals we cannot
// optimize once the CreateShallowObjectLiteral stub is in sync with the TF
// optimizations.
int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
builder()->CreateObjectLiteral(entry, literal_index, flags, literal);
}
}
void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
expr->InitDepthAndFlags(); expr->InitDepthAndFlags();
...@@ -2155,11 +2176,7 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -2155,11 +2176,7 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
entry = builder()->AllocateDeferredConstantPoolEntry(); entry = builder()->AllocateDeferredConstantPoolEntry();
object_literals_.push_back(std::make_pair(expr, entry)); object_literals_.push_back(std::make_pair(expr, entry));
} }
// TODO(cbruni): Directly generate runtime call for literals we cannot BuildCreateObjectLiteral(literal, flags, entry);
// optimize once the CreateShallowObjectLiteral stub is in sync with the TF
// optimizations.
int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
builder()->CreateObjectLiteral(entry, literal_index, flags, literal);
} }
// Store computed values into the literal. // Store computed values into the literal.
......
...@@ -187,6 +187,7 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> { ...@@ -187,6 +187,7 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
ZonePtrList<Expression>* elements, ZonePtrList<Expression>* elements,
bool skip_constants); bool skip_constants);
void BuildCreateObjectLiteral(Register literal, uint8_t flags, size_t entry);
void AllocateTopLevelRegisters(); void AllocateTopLevelRegisters();
void VisitArgumentsObject(Variable* variable); void VisitArgumentsObject(Variable* variable);
void VisitRestArgumentsArray(Variable* rest); void VisitRestArgumentsArray(Variable* rest);
......
...@@ -316,7 +316,7 @@ MaybeHandle<JSObject> DeepCopy(Handle<JSObject> object, ...@@ -316,7 +316,7 @@ MaybeHandle<JSObject> DeepCopy(Handle<JSObject> object,
return copy; return copy;
} }
struct ObjectBoilerplate { struct ObjectLiteralHelper {
static Handle<JSObject> Create(Isolate* isolate, static Handle<JSObject> Create(Isolate* isolate,
Handle<HeapObject> description, int flags, Handle<HeapObject> description, int flags,
PretenureFlag pretenure_flag) { PretenureFlag pretenure_flag) {
...@@ -391,7 +391,7 @@ struct ObjectBoilerplate { ...@@ -391,7 +391,7 @@ struct ObjectBoilerplate {
} }
}; };
struct ArrayBoilerplate { struct ArrayLiteralHelper {
static Handle<JSObject> Create(Isolate* isolate, static Handle<JSObject> Create(Isolate* isolate,
Handle<HeapObject> description, int flags, Handle<HeapObject> description, int flags,
PretenureFlag pretenure_flag) { PretenureFlag pretenure_flag) {
...@@ -454,20 +454,43 @@ Handle<Object> InnerCreateBoilerplate(Isolate* isolate, ...@@ -454,20 +454,43 @@ Handle<Object> InnerCreateBoilerplate(Isolate* isolate,
if (description->IsObjectBoilerplateDescription()) { if (description->IsObjectBoilerplateDescription()) {
Handle<ObjectBoilerplateDescription> object_boilerplate_description = Handle<ObjectBoilerplateDescription> object_boilerplate_description =
Handle<ObjectBoilerplateDescription>::cast(description); Handle<ObjectBoilerplateDescription>::cast(description);
return ObjectBoilerplate::Create(isolate, object_boilerplate_description, return ObjectLiteralHelper::Create(isolate, object_boilerplate_description,
object_boilerplate_description->flags(), object_boilerplate_description->flags(),
pretenure_flag); pretenure_flag);
} else { } else {
DCHECK(description->IsArrayBoilerplateDescription()); DCHECK(description->IsArrayBoilerplateDescription());
Handle<ArrayBoilerplateDescription> array_boilerplate_description = Handle<ArrayBoilerplateDescription> array_boilerplate_description =
Handle<ArrayBoilerplateDescription>::cast(description); Handle<ArrayBoilerplateDescription>::cast(description);
return ArrayBoilerplate::Create( return ArrayLiteralHelper::Create(
isolate, array_boilerplate_description, isolate, array_boilerplate_description,
array_boilerplate_description->elements_kind(), pretenure_flag); array_boilerplate_description->elements_kind(), pretenure_flag);
} }
} }
template <typename Boilerplate> inline DeepCopyHints DecodeCopyHints(int flags) {
DeepCopyHints copy_hints =
(flags & AggregateLiteral::kIsShallow) ? kObjectIsShallow : kNoHints;
if (FLAG_track_double_fields && !FLAG_unbox_double_fields) {
// Make sure we properly clone mutable heap numbers on 32-bit platforms.
copy_hints = kNoHints;
}
return copy_hints;
}
template <typename LiteralHelper>
MaybeHandle<JSObject> CreateLiteralWithoutAllocationSite(
Isolate* isolate, Handle<HeapObject> description, int flags) {
Handle<JSObject> literal =
LiteralHelper::Create(isolate, description, flags, NOT_TENURED);
DeepCopyHints copy_hints = DecodeCopyHints(flags);
if (copy_hints == kNoHints) {
DeprecationUpdateContext update_context(isolate);
RETURN_ON_EXCEPTION(isolate, DeepWalk(literal, &update_context), JSObject);
}
return literal;
}
template <typename LiteralHelper>
MaybeHandle<JSObject> CreateLiteral(Isolate* isolate, MaybeHandle<JSObject> CreateLiteral(Isolate* isolate,
Handle<FeedbackVector> vector, Handle<FeedbackVector> vector,
int literals_index, int literals_index,
...@@ -475,12 +498,7 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate, ...@@ -475,12 +498,7 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate,
FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index)); FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index));
CHECK(literals_slot.ToInt() < vector->length()); CHECK(literals_slot.ToInt() < vector->length());
Handle<Object> literal_site(vector->Get(literals_slot)->ToObject(), isolate); Handle<Object> literal_site(vector->Get(literals_slot)->ToObject(), isolate);
DeepCopyHints copy_hints = DeepCopyHints copy_hints = DecodeCopyHints(flags);
(flags & AggregateLiteral::kIsShallow) ? kObjectIsShallow : kNoHints;
if (FLAG_track_double_fields && !FLAG_unbox_double_fields) {
// Make sure we properly clone mutable heap numbers on 32-bit platforms.
copy_hints = kNoHints;
}
Handle<AllocationSite> site; Handle<AllocationSite> site;
Handle<JSObject> boilerplate; Handle<JSObject> boilerplate;
...@@ -492,21 +510,13 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate, ...@@ -492,21 +510,13 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate,
// Eagerly create AllocationSites for literals that contain an Array. // Eagerly create AllocationSites for literals that contain an Array.
bool needs_initial_allocation_site = bool needs_initial_allocation_site =
(flags & AggregateLiteral::kNeedsInitialAllocationSite) != 0; (flags & AggregateLiteral::kNeedsInitialAllocationSite) != 0;
// TODO(cbruni): Even in the case where we need an initial allocation site
// we could still create the boilerplate lazily to save memory.
if (!needs_initial_allocation_site && if (!needs_initial_allocation_site &&
IsUninitializedLiteralSite(*literal_site)) { IsUninitializedLiteralSite(*literal_site)) {
PreInitializeLiteralSite(vector, literals_slot); PreInitializeLiteralSite(vector, literals_slot);
boilerplate = return CreateLiteralWithoutAllocationSite<LiteralHelper>(
Boilerplate::Create(isolate, description, flags, NOT_TENURED); isolate, description, flags);
if (copy_hints == kNoHints) {
DeprecationUpdateContext update_context(isolate);
RETURN_ON_EXCEPTION(isolate, DeepWalk(boilerplate, &update_context),
JSObject);
}
return boilerplate;
} else { } else {
boilerplate = Boilerplate::Create(isolate, description, flags, TENURED); boilerplate = LiteralHelper::Create(isolate, description, flags, TENURED);
} }
// Install AllocationSite objects. // Install AllocationSite objects.
AllocationSiteCreationContext creation_context(isolate); AllocationSiteCreationContext creation_context(isolate);
...@@ -540,8 +550,18 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { ...@@ -540,8 +550,18 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
CONVERT_ARG_HANDLE_CHECKED(ObjectBoilerplateDescription, description, 2); CONVERT_ARG_HANDLE_CHECKED(ObjectBoilerplateDescription, description, 2);
CONVERT_SMI_ARG_CHECKED(flags, 3); CONVERT_SMI_ARG_CHECKED(flags, 3);
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, CreateLiteral<ObjectBoilerplate>(isolate, vector, literals_index, isolate, CreateLiteral<ObjectLiteralHelper>(
description, flags)); isolate, vector, literals_index, description, flags));
}
RUNTIME_FUNCTION(Runtime_CreateObjectLiteralWithoutAllocationSite) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(ObjectBoilerplateDescription, description, 0);
CONVERT_SMI_ARG_CHECKED(flags, 1);
RETURN_RESULT_OR_FAILURE(
isolate, CreateLiteralWithoutAllocationSite<ObjectLiteralHelper>(
isolate, description, flags));
} }
RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
...@@ -552,8 +572,8 @@ RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { ...@@ -552,8 +572,8 @@ RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
CONVERT_ARG_HANDLE_CHECKED(ArrayBoilerplateDescription, elements, 2); CONVERT_ARG_HANDLE_CHECKED(ArrayBoilerplateDescription, elements, 2);
CONVERT_SMI_ARG_CHECKED(flags, 3); CONVERT_SMI_ARG_CHECKED(flags, 3);
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, CreateLiteral<ArrayBoilerplate>(isolate, vector, literals_index, isolate, CreateLiteral<ArrayLiteralHelper>(
elements, flags)); isolate, vector, literals_index, elements, flags));
} }
RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) { RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) {
......
...@@ -285,6 +285,7 @@ namespace internal { ...@@ -285,6 +285,7 @@ namespace internal {
#define FOR_EACH_INTRINSIC_LITERALS(F) \ #define FOR_EACH_INTRINSIC_LITERALS(F) \
F(CreateArrayLiteral, 4, 1) \ F(CreateArrayLiteral, 4, 1) \
F(CreateObjectLiteral, 4, 1) \ F(CreateObjectLiteral, 4, 1) \
F(CreateObjectLiteralWithoutAllocationSite, 2, 1) \
F(CreateRegExpLiteral, 4, 1) F(CreateRegExpLiteral, 4, 1)
#define FOR_EACH_INTRINSIC_MATHS(F) F(GenerateRandomNumbers, 0, 1) #define FOR_EACH_INTRINSIC_MATHS(F) F(GenerateRandomNumbers, 0, 1)
......
...@@ -3678,6 +3678,7 @@ TEST(AllocationSiteCreation) { ...@@ -3678,6 +3678,7 @@ TEST(AllocationSiteCreation) {
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap(); Heap* heap = isolate->heap();
HandleScope scope(isolate); HandleScope scope(isolate);
i::FLAG_enable_one_shot_optimization = true;
// Array literals. // Array literals.
CheckNumberOfAllocations(heap, "(function f1() { return []; })()", 1, 0); CheckNumberOfAllocations(heap, "(function f1() { return []; })()", 1, 0);
...@@ -3727,6 +3728,52 @@ TEST(AllocationSiteCreation) { ...@@ -3727,6 +3728,52 @@ TEST(AllocationSiteCreation) {
// No new AllocationSites created on the second invocation. // No new AllocationSites created on the second invocation.
CheckNumberOfAllocations(heap, "f9(); ", 0, 0); CheckNumberOfAllocations(heap, "f9(); ", 0, 0);
// No allocation sites for literals in an iife/top level code even if it has
// array subliterals
CheckNumberOfAllocations(heap,
R"(
(function f10() {
return {a: [1], b: [2]};
})();
)",
0, 0);
CheckNumberOfAllocations(heap,
R"(
l = {
a: 1,
b: {
c: [5],
}
};
)",
0, 0);
// Eagerly create allocation sites for literals within a loop of iife or
// top-level code
CheckNumberOfAllocations(heap,
R"(
(function f11() {
while(true) {
return {a: [1], b: [2]};
}
})();
)",
1, 2);
CheckNumberOfAllocations(heap,
R"(
for (i = 0; i < 1; ++i) {
l = {
a: 1,
b: {
c: [5],
}
};
}
)",
1, 1);
} }
TEST(CellsInOptimizedCodeAreWeak) { TEST(CellsInOptimizedCodeAreWeak) {
......
...@@ -385,6 +385,7 @@ void BytecodeExpectationsPrinter::PrintExpectation( ...@@ -385,6 +385,7 @@ void BytecodeExpectationsPrinter::PrintExpectation(
: snippet; : snippet;
i::FLAG_enable_one_shot_optimization = oneshot_opt_; i::FLAG_enable_one_shot_optimization = oneshot_opt_;
i::FLAG_compilation_cache = false;
i::Handle<i::BytecodeArray> bytecode_array; i::Handle<i::BytecodeArray> bytecode_array;
if (module_) { if (module_) {
CHECK(top_level_ && !wrap_); CHECK(top_level_ && !wrap_);
......
...@@ -33,7 +33,7 @@ class BytecodeExpectationsPrinter final { ...@@ -33,7 +33,7 @@ class BytecodeExpectationsPrinter final {
wrap_(true), wrap_(true),
top_level_(false), top_level_(false),
print_callee_(false), print_callee_(false),
oneshot_opt_(true), oneshot_opt_(false),
test_function_name_(kDefaultTopFunctionName) {} test_function_name_(kDefaultTopFunctionName) {}
void PrintExpectation(std::ostream& stream, // NOLINT void PrintExpectation(std::ostream& stream, // NOLINT
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
wrap: no wrap: no
top level: yes top level: yes
print callee: yes print callee: yes
oneshot opt: yes
--- ---
snippet: " snippet: "
...@@ -270,15 +271,18 @@ snippet: " ...@@ -270,15 +271,18 @@ snippet: "
" "
frame size: 6 frame size: 6
parameter count: 1 parameter count: 1
bytecode array length: 115 bytecode array length: 121
bytecodes: [ bytecodes: [
B(CreateMappedArguments), B(CreateMappedArguments),
B(Star), R(0), B(Star), R(0),
/* 16 E> */ B(StackCheck), /* 16 E> */ B(StackCheck),
/* 29 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41), R(1), /* 29 S> */ B(LdaConstant), U8(0),
B(Ldar), R(1), B(Star), R(2),
/* 31 E> */ B(StaGlobal), U8(1), U8(1), B(LdaSmi), I8(41),
/* 95 S> */ B(LdaGlobal), U8(1), U8(3), B(Star), R(3),
B(CallRuntime), U16(Runtime::kCreateObjectLiteralWithoutAllocationSite), R(2), U8(2),
/* 31 E> */ B(StaGlobal), U8(1), U8(0),
/* 95 S> */ B(LdaGlobal), U8(1), U8(2),
B(Star), R(1), B(Star), R(1),
B(LdaConstant), U8(2), B(LdaConstant), U8(2),
B(Star), R(3), B(Star), R(3),
...@@ -286,9 +290,9 @@ bytecodes: [ ...@@ -286,9 +290,9 @@ bytecodes: [
/* 101 E> */ B(InvokeIntrinsic), U8(Runtime::k_GetProperty), R(2), U8(2), /* 101 E> */ B(InvokeIntrinsic), U8(Runtime::k_GetProperty), R(2), U8(2),
B(Star), R(1), B(Star), R(1),
B(LdaSmi), I8(3), B(LdaSmi), I8(3),
/* 104 E> */ B(TestLessThan), R(1), U8(5), /* 104 E> */ B(TestLessThan), R(1), U8(4),
B(JumpIfFalse), U8(28), B(JumpIfFalse), U8(28),
/* 121 S> */ B(LdaGlobal), U8(1), U8(3), /* 121 S> */ B(LdaGlobal), U8(1), U8(2),
B(Star), R(1), B(Star), R(1),
B(LdaSmi), I8(3), B(LdaSmi), I8(3),
B(Star), R(4), B(Star), R(4),
...@@ -299,9 +303,9 @@ bytecodes: [ ...@@ -299,9 +303,9 @@ bytecodes: [
B(Mov), R(1), R(2), B(Mov), R(1), R(2),
/* 126 E> */ B(CallRuntime), U16(Runtime::kSetProperty), R(2), U8(4), /* 126 E> */ B(CallRuntime), U16(Runtime::kSetProperty), R(2), U8(4),
B(Jump), U8(40), B(Jump), U8(40),
/* 158 S> */ B(LdaGlobal), U8(1), U8(3), /* 158 S> */ B(LdaGlobal), U8(1), U8(2),
B(Star), R(1), B(Star), R(1),
/* 165 E> */ B(LdaGlobal), U8(1), U8(3), /* 165 E> */ B(LdaGlobal), U8(1), U8(2),
B(Star), R(2), B(Star), R(2),
B(LdaConstant), U8(3), B(LdaConstant), U8(3),
B(Star), R(4), B(Star), R(4),
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
wrap: no wrap: no
top level: yes top level: yes
print callee: yes print callee: yes
oneshot opt: no
--- ---
snippet: " snippet: "
...@@ -55,8 +54,8 @@ snippet: " ...@@ -55,8 +54,8 @@ snippet: "
(function() { (function() {
l = { l = {
'a': 3.3, 'a': 4.3,
'b': 4.4 'b': 3.4
}; };
if (l.a < 3) { if (l.a < 3) {
l.a = 3; l.a = 3;
......
...@@ -508,9 +508,9 @@ snippet: " ...@@ -508,9 +508,9 @@ snippet: "
import * as foo from \"bar\" import * as foo from \"bar\"
foo.f(foo, foo.x); foo.f(foo, foo.x);
" "
frame size: 10 frame size: 8
parameter count: 2 parameter count: 2
bytecode array length: 103 bytecode array length: 89
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(1), B(SwitchOnGeneratorState), R(0), U8(0), U8(1),
B(LdaConstant), U8(1), B(LdaConstant), U8(1),
...@@ -537,17 +537,11 @@ bytecodes: [ ...@@ -537,17 +537,11 @@ bytecodes: [
/* 0 E> */ B(Throw), /* 0 E> */ B(Throw),
B(Ldar), R(4), B(Ldar), R(4),
/* 46 S> */ B(Return), /* 46 S> */ B(Return),
/* 27 S> */ B(LdaConstant), U8(4), /* 31 S> */ B(LdaNamedProperty), R(1), U8(4), U8(0),
B(Star), R(7),
B(Mov), R(1), R(6),
/* 31 E> */ B(InvokeIntrinsic), U8(Runtime::k_GetProperty), R(6), U8(2),
B(Star), R(4), B(Star), R(4),
B(LdaConstant), U8(5), /* 42 E> */ B(LdaNamedProperty), R(1), U8(5), U8(2),
B(Star), R(9),
B(Mov), R(1), R(8),
/* 42 E> */ B(InvokeIntrinsic), U8(Runtime::k_GetProperty), R(8), U8(2),
B(Star), R(7), B(Star), R(7),
/* 31 E> */ B(CallProperty2), R(4), R(1), R(1), R(7), U8(0), /* 31 E> */ B(CallProperty2), R(4), R(1), R(1), R(7), U8(4),
B(Star), R(2), B(Star), R(2),
/* 46 S> */ B(Return), /* 46 S> */ B(Return),
] ]
......
...@@ -5,19 +5,18 @@ ...@@ -5,19 +5,18 @@
--- ---
wrap: no wrap: no
top level: yes top level: yes
oneshot opt: no
--- ---
snippet: " snippet: "
l = { l = {
'a': 1.1, 'aa': 1.1,
'b': 2.2 'bb': 2.2
}; };
v = l['a'] + l['b']; v = l['aa'] + l['bb'];
l['b'] = 7; l['bb'] = 7;
l['a'] = l['b']; l['aa'] = l['bb'];
" "
frame size: 3 frame size: 3
...@@ -28,35 +27,35 @@ bytecodes: [ ...@@ -28,35 +27,35 @@ bytecodes: [
/* 7 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41), R(1), /* 7 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41), R(1),
B(Ldar), R(1), B(Ldar), R(1),
/* 9 E> */ B(StaGlobal), U8(1), U8(1), /* 9 E> */ B(StaGlobal), U8(1), U8(1),
/* 64 S> */ B(LdaGlobal), U8(1), U8(4), /* 66 S> */ B(LdaGlobal), U8(1), U8(4),
B(Star), R(1), B(Star), R(1),
/* 69 E> */ B(LdaNamedProperty), R(1), U8(2), U8(6), /* 71 E> */ B(LdaNamedProperty), R(1), U8(2), U8(6),
B(Star), R(1), B(Star), R(1),
/* 77 E> */ B(LdaGlobal), U8(1), U8(4), /* 80 E> */ B(LdaGlobal), U8(1), U8(4),
B(Star), R(2), B(Star), R(2),
/* 78 E> */ B(LdaNamedProperty), R(2), U8(3), U8(8), /* 81 E> */ B(LdaNamedProperty), R(2), U8(3), U8(8),
/* 75 E> */ B(Add), R(1), U8(3), /* 78 E> */ B(Add), R(1), U8(3),
/* 66 E> */ B(StaGlobal), U8(4), U8(10), /* 68 E> */ B(StaGlobal), U8(4), U8(10),
/* 91 S> */ B(LdaGlobal), U8(1), U8(4), /* 95 S> */ B(LdaGlobal), U8(1), U8(4),
B(Star), R(1), B(Star), R(1),
B(LdaSmi), I8(7), B(LdaSmi), I8(7),
/* 98 E> */ B(StaNamedProperty), R(1), U8(3), U8(12), /* 103 E> */ B(StaNamedProperty), R(1), U8(3), U8(12),
/* 109 S> */ B(LdaGlobal), U8(1), U8(4), /* 114 S> */ B(LdaGlobal), U8(1), U8(4),
B(Star), R(1), B(Star), R(1),
/* 118 E> */ B(LdaGlobal), U8(1), U8(4), /* 124 E> */ B(LdaGlobal), U8(1), U8(4),
B(Star), R(2), B(Star), R(2),
/* 119 E> */ B(LdaNamedProperty), R(2), U8(3), U8(8), /* 125 E> */ B(LdaNamedProperty), R(2), U8(3), U8(8),
B(Star), R(2), B(Star), R(2),
/* 116 E> */ B(StaNamedProperty), R(1), U8(2), U8(14), /* 122 E> */ B(StaNamedProperty), R(1), U8(2), U8(14),
B(Mov), R(2), R(0), B(Mov), R(2), R(0),
B(Ldar), R(0), B(Ldar), R(0),
/* 127 S> */ B(Return), /* 139 S> */ B(Return),
] ]
constant pool: [ constant pool: [
OBJECT_BOILERPLATE_DESCRIPTION_TYPE, OBJECT_BOILERPLATE_DESCRIPTION_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["l"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["l"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["a"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["aa"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["b"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["bb"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["v"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["v"],
] ]
handlers: [ handlers: [
...@@ -66,8 +65,8 @@ handlers: [ ...@@ -66,8 +65,8 @@ handlers: [
snippet: " snippet: "
l = { l = {
'cc': 1.1, 'cc': 3.1,
'dd': 2.2 'dd': 4.2
}; };
if (l['cc'] < 3) { if (l['cc'] < 3) {
l['cc'] = 3; l['cc'] = 3;
...@@ -107,7 +106,7 @@ bytecodes: [ ...@@ -107,7 +106,7 @@ bytecodes: [
B(Mov), R(2), R(0), B(Mov), R(2), R(0),
B(Ldar), R(2), B(Ldar), R(2),
B(Ldar), R(0), B(Ldar), R(0),
/* 156 S> */ B(Return), /* 155 S> */ B(Return),
] ]
constant pool: [ constant pool: [
OBJECT_BOILERPLATE_DESCRIPTION_TYPE, OBJECT_BOILERPLATE_DESCRIPTION_TYPE,
......
...@@ -43,7 +43,7 @@ class ProgramOptions final { ...@@ -43,7 +43,7 @@ class ProgramOptions final {
module_(false), module_(false),
top_level_(false), top_level_(false),
print_callee_(false), print_callee_(false),
oneshot_opt_(true), oneshot_opt_(false),
do_expressions_(false), do_expressions_(false),
async_iteration_(false), async_iteration_(false),
public_fields_(false), public_fields_(false),
...@@ -332,7 +332,7 @@ void ProgramOptions::PrintHeader(std::ostream& stream) const { // NOLINT ...@@ -332,7 +332,7 @@ void ProgramOptions::PrintHeader(std::ostream& stream) const { // NOLINT
if (module_) stream << "\nmodule: yes"; if (module_) stream << "\nmodule: yes";
if (top_level_) stream << "\ntop level: yes"; if (top_level_) stream << "\ntop level: yes";
if (print_callee_) stream << "\nprint callee: yes"; if (print_callee_) stream << "\nprint callee: yes";
if (!oneshot_opt_) stream << "\noneshot opt: no"; if (oneshot_opt_) stream << "\noneshot opt: yes";
if (do_expressions_) stream << "\ndo expressions: yes"; if (do_expressions_) stream << "\ndo expressions: yes";
if (async_iteration_) stream << "\nasync iteration: yes"; if (async_iteration_) stream << "\nasync iteration: yes";
if (public_fields_) stream << "\npublic fields: yes"; if (public_fields_) stream << "\npublic fields: yes";
......
...@@ -138,8 +138,9 @@ static inline void ltrim(std::string& str) { ...@@ -138,8 +138,9 @@ static inline void ltrim(std::string& str) {
// inplace right trim // inplace right trim
static inline void rtrim(std::string& str) { static inline void rtrim(std::string& str) {
str.erase(std::find_if(str.begin(), str.end(), str.erase(std::find_if(str.rbegin(), str.rend(),
[](unsigned char ch) { return !std::isspace(ch); }), [](unsigned char ch) { return !std::isspace(ch); })
.base(),
str.end()); str.end());
} }
...@@ -436,6 +437,8 @@ TEST(PropertyLoadStoreOneShot) { ...@@ -436,6 +437,8 @@ TEST(PropertyLoadStoreOneShot) {
BytecodeExpectationsPrinter printer(CcTest::isolate()); BytecodeExpectationsPrinter printer(CcTest::isolate());
printer.set_wrap(false); printer.set_wrap(false);
printer.set_top_level(true); printer.set_top_level(true);
printer.set_oneshot_opt(true);
const char* snippets[] = { const char* snippets[] = {
R"( R"(
l = { l = {
...@@ -502,7 +505,6 @@ TEST(PropertyLoadStoreWithoutOneShot) { ...@@ -502,7 +505,6 @@ TEST(PropertyLoadStoreWithoutOneShot) {
BytecodeExpectationsPrinter printer(CcTest::isolate()); BytecodeExpectationsPrinter printer(CcTest::isolate());
printer.set_wrap(false); printer.set_wrap(false);
printer.set_top_level(true); printer.set_top_level(true);
printer.set_oneshot_opt(false);
const char* snippets[] = { const char* snippets[] = {
R"( R"(
...@@ -539,6 +541,7 @@ TEST(IIFEWithOneshotOpt) { ...@@ -539,6 +541,7 @@ TEST(IIFEWithOneshotOpt) {
printer.set_wrap(false); printer.set_wrap(false);
printer.set_top_level(true); printer.set_top_level(true);
printer.set_print_callee(true); printer.set_print_callee(true);
printer.set_oneshot_opt(true);
const char* snippets[] = { const char* snippets[] = {
// No feedback vectors for top-level loads/store named property in an IIFE // No feedback vectors for top-level loads/store named property in an IIFE
...@@ -614,7 +617,6 @@ TEST(IIFEWithoutOneshotOpt) { ...@@ -614,7 +617,6 @@ TEST(IIFEWithoutOneshotOpt) {
printer.set_wrap(false); printer.set_wrap(false);
printer.set_top_level(true); printer.set_top_level(true);
printer.set_print_callee(true); printer.set_print_callee(true);
printer.set_oneshot_opt(false);
const char* snippets[] = { const char* snippets[] = {
R"( R"(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment