[Interpreter] Fix a register allocation bug and add a DCHECK.
BUG=v8:4280 LOG=N Review URL: https://codereview.chromium.org/1413703007 Cr-Commit-Position: refs/heads/master@{#31604}
This commit is contained in:
parent
f1aa556278
commit
f85c410626
@ -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<int>(count) > next_consecutive_count_) {
|
||||
next_consecutive_register_ =
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -2988,15 +2988,21 @@ TEST(CountOperators) {
|
||||
FeedbackVectorSpec feedback_spec(&zone);
|
||||
FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot();
|
||||
FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot();
|
||||
|
||||
Handle<i::TypeFeedbackVector> vector =
|
||||
i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
|
||||
|
||||
FeedbackVectorSpec store_feedback_spec(&zone);
|
||||
FeedbackVectorSlot store_slot = store_feedback_spec.AddStoreICSlot();
|
||||
Handle<i::TypeFeedbackVector> 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<InstanceType> 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++) {
|
||||
|
Loading…
Reference in New Issue
Block a user