diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc index 26b5414b3a..93a86de5cd 100644 --- a/src/interpreter/bytecode-array-builder.cc +++ b/src/interpreter/bytecode-array-builder.cc @@ -1061,6 +1061,15 @@ Register TemporaryRegisterScope::NewRegister() { } +bool TemporaryRegisterScope::RegisterIsAllocatedInThisScope( + Register reg) const { + for (auto i = allocated_.begin(); i != allocated_.end(); i++) { + if (*i == reg.index()) return true; + } + return false; +} + + void TemporaryRegisterScope::PrepareForConsecutiveAllocations(size_t count) { if (static_cast(count) > next_consecutive_count_) { next_consecutive_register_ = diff --git a/src/interpreter/bytecode-array-builder.h b/src/interpreter/bytecode-array-builder.h index 15ff07e93d..4ee7be2b5f 100644 --- a/src/interpreter/bytecode-array-builder.h +++ b/src/interpreter/bytecode-array-builder.h @@ -316,6 +316,8 @@ class TemporaryRegisterScope { void PrepareForConsecutiveAllocations(size_t count); Register NextConsecutiveRegister(); + bool RegisterIsAllocatedInThisScope(Register reg) const; + private: void* operator new(size_t size); void operator delete(void* p); diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc index 95d3f921b1..110a3e84dc 100644 --- a/src/interpreter/bytecode-generator.cc +++ b/src/interpreter/bytecode-generator.cc @@ -193,6 +193,8 @@ class BytecodeGenerator::ExpressionResultScope { bool result_identified() const { return result_identified_; } + const TemporaryRegisterScope* allocator() const { return &allocator_; } + private: BytecodeGenerator* generator_; Expression::Context kind_; @@ -252,7 +254,8 @@ class BytecodeGenerator::RegisterResultScope final virtual void SetResultInRegister(Register reg) { DCHECK(builder()->RegisterIsParameterOrLocal(reg) || - builder()->RegisterIsTemporary(reg)); + (builder()->RegisterIsTemporary(reg) && + !allocator()->RegisterIsAllocatedInThisScope(reg))); result_register_ = reg; set_result_identified(); } @@ -475,6 +478,8 @@ void BytecodeGenerator::VisitDeclarations( void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { + // TODO(rmcilroy): Replace this with a StatementResultScope when it exists. + EffectResultScope effect_scope(this); VisitForEffect(stmt->expression()); } @@ -522,6 +527,7 @@ void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { + EffectResultScope effect_scope(this); VisitForAccumulatorValue(stmt->expression()); builder()->Return(); } @@ -1484,7 +1490,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { // Save result for postfix expressions. if (is_postfix) { - old_value = execution_result()->NewRegister(); + old_value = execution_result()->outer()->NewRegister(); builder()->StoreAccumulatorInRegister(old_value); } diff --git a/test/cctest/interpreter/test-bytecode-generator.cc b/test/cctest/interpreter/test-bytecode-generator.cc index ea1a8b2619..2dd5167cb2 100644 --- a/test/cctest/interpreter/test-bytecode-generator.cc +++ b/test/cctest/interpreter/test-bytecode-generator.cc @@ -2988,15 +2988,21 @@ TEST(CountOperators) { FeedbackVectorSpec feedback_spec(&zone); FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot(); - Handle vector = i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); + FeedbackVectorSpec store_feedback_spec(&zone); + FeedbackVectorSlot store_slot = store_feedback_spec.AddStoreICSlot(); + Handle store_vector = + i::NewTypeFeedbackVector(helper.isolate(), &store_feedback_spec); + int closure = Register::function_closure().index(); int first_context_slot = Context::MIN_CONTEXT_SLOTS; int object_literal_flags = ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; + int array_literal_flags = + ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements; ExpectedSnippet snippets[] = { {"var a = 1; return ++a;", @@ -3179,6 +3185,28 @@ TEST(CountOperators) { }, 1, {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, + {"var idx = 1; var a = [1, 2]; return a[idx++] = 2;", + 3 * kPointerSize, + 1, + 26, + { + B(LdaSmi8), U8(1), // + B(Star), R(0), // + B(LdaConstant), U8(0), // + B(CreateArrayLiteral), U8(0), U8(array_literal_flags), // + B(Star), R(1), // + B(Ldar), R(0), // + B(ToNumber), // + B(Star), R(2), // + B(Inc), // + B(Star), R(0), // + B(LdaSmi8), U8(2), // + B(KeyedStoreICSloppy), R(1), R(2), // + U8(store_vector->GetIndex(store_slot)), // + B(Return), // + }, + 1, + {InstanceType::FIXED_ARRAY_TYPE}}, }; for (size_t i = 0; i < arraysize(snippets); i++) {