Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(311)

Unified Diff: src/full-codegen/x64/full-codegen-x64.cc

Issue 1706283002: [fullcodegen] Implement operand stack depth tracking. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Turn off verification. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/full-codegen/ppc/full-codegen-ppc.cc ('k') | src/full-codegen/x87/full-codegen-x87.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/full-codegen/x64/full-codegen-x64.cc
diff --git a/src/full-codegen/x64/full-codegen-x64.cc b/src/full-codegen/x64/full-codegen-x64.cc
index b442fc73f9d821eee7b26969c66753639c96431a..910b2cf9f062b578ba7d26d74943e85c3a1856d9 100644
--- a/src/full-codegen/x64/full-codegen-x64.cc
+++ b/src/full-codegen/x64/full-codegen-x64.cc
@@ -118,6 +118,7 @@ void FullCodeGenerator::Generate() {
int locals_count = info->scope()->num_stack_slots();
// Generators allocate locals, if any, in context slots.
DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0);
+ OperandStackDepthIncrement(locals_count);
if (locals_count == 1) {
__ PushRoot(Heap::kUndefinedValueRootIndex);
} else if (locals_count > 1) {
@@ -431,7 +432,7 @@ void FullCodeGenerator::EmitReturnSequence() {
void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
DCHECK(var->IsStackAllocated() || var->IsContextSlot());
MemOperand operand = codegen()->VarOperand(var, result_register());
- __ Push(operand);
+ codegen()->PushOperand(operand);
}
@@ -447,6 +448,7 @@ void FullCodeGenerator::AccumulatorValueContext::Plug(
void FullCodeGenerator::StackValueContext::Plug(
Heap::RootListIndex index) const {
+ codegen()->OperandStackDepthIncrement(1);
__ PushRoot(index);
}
@@ -484,6 +486,7 @@ void FullCodeGenerator::AccumulatorValueContext::Plug(
void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
+ codegen()->OperandStackDepthIncrement(1);
if (lit->IsSmi()) {
__ SafePush(Smi::cast(*lit));
} else {
@@ -522,41 +525,14 @@ void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
}
-void FullCodeGenerator::EffectContext::DropAndPlug(int count,
- Register reg) const {
- DCHECK(count > 0);
- __ Drop(count);
-}
-
-
-void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
- int count,
- Register reg) const {
- DCHECK(count > 0);
- __ Drop(count);
- __ Move(result_register(), reg);
-}
-
-
void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
Register reg) const {
DCHECK(count > 0);
- if (count > 1) __ Drop(count - 1);
+ if (count > 1) codegen()->DropOperands(count - 1);
__ movp(Operand(rsp, 0), reg);
}
-void FullCodeGenerator::TestContext::DropAndPlug(int count,
- Register reg) const {
- DCHECK(count > 0);
- // For simplicity we always test the accumulator register.
- __ Drop(count);
- __ Move(result_register(), reg);
- codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
- codegen()->DoTest(this);
-}
-
-
void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
Label* materialize_false) const {
DCHECK(materialize_true == materialize_false);
@@ -580,6 +556,7 @@ void FullCodeGenerator::AccumulatorValueContext::Plug(
void FullCodeGenerator::StackValueContext::Plug(
Label* materialize_true,
Label* materialize_false) const {
+ codegen()->OperandStackDepthIncrement(1);
Label done;
__ bind(materialize_true);
__ Push(isolate()->factory()->true_value());
@@ -605,6 +582,7 @@ void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
+ codegen()->OperandStackDepthIncrement(1);
Heap::RootListIndex value_root_index =
flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
__ PushRoot(value_root_index);
@@ -842,10 +820,10 @@ void FullCodeGenerator::VisitFunctionDeclaration(
case VariableLocation::LOOKUP: {
Comment cmnt(masm_, "[ FunctionDeclaration");
- __ Push(variable->name());
+ PushOperand(variable->name());
VisitForStackValue(declaration->fun());
- __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
- __ CallRuntime(Runtime::kDeclareLookupSlot);
+ PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
+ CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
break;
}
}
@@ -942,7 +920,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
// Discard the test value and jump to the default if present, otherwise to
// the end of the statement.
__ bind(&next_test);
- __ Drop(1); // Switch value is no longer needed.
+ DropOperands(1); // Switch value is no longer needed.
if (default_clause == NULL) {
__ jmp(nested_statement.break_label());
} else {
@@ -976,6 +954,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Get the object to enumerate over.
SetExpressionAsStatementPosition(stmt->enumerable());
VisitForAccumulatorValue(stmt->enumerable());
+ OperandStackDepthIncrement(ForIn::kElementCount);
// If the object is null or undefined, skip over the loop, otherwise convert
// it to a JS receiver. See ECMA-262 version 5, section 12.6.4.
@@ -1137,6 +1116,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Remove the pointers stored on the stack.
__ bind(loop_statement.break_label());
__ addp(rsp, Immediate(5 * kPointerSize));
+ OperandStackDepthDecrement(ForIn::kElementCount);
// Exit and decrement the loop depth.
PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
@@ -1408,6 +1388,7 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
Expression* expression = (property == NULL) ? NULL : property->value();
if (expression == NULL) {
+ OperandStackDepthIncrement(1);
__ PushRoot(Heap::kNullValueRootIndex);
} else {
VisitForStackValue(expression);
@@ -1456,7 +1437,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Literal* key = property->key()->AsLiteral();
Expression* value = property->value();
if (!result_saved) {
- __ Push(rax); // Save result on the stack
+ PushOperand(rax); // Save result on the stack
result_saved = true;
}
switch (property->kind()) {
@@ -1486,24 +1467,24 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
}
break;
}
- __ Push(Operand(rsp, 0)); // Duplicate receiver.
+ PushOperand(Operand(rsp, 0)); // Duplicate receiver.
VisitForStackValue(key);
VisitForStackValue(value);
if (property->emit_store()) {
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());
}
- __ Push(Smi::FromInt(SLOPPY)); // Language mode
- __ CallRuntime(Runtime::kSetProperty);
+ PushOperand(Smi::FromInt(SLOPPY)); // Language mode
+ CallRuntimeWithOperands(Runtime::kSetProperty);
} else {
- __ Drop(3);
+ DropOperands(3);
}
break;
case ObjectLiteral::Property::PROTOTYPE:
- __ Push(Operand(rsp, 0)); // Duplicate receiver.
+ PushOperand(Operand(rsp, 0)); // Duplicate receiver.
VisitForStackValue(value);
DCHECK(property->emit_store());
- __ CallRuntime(Runtime::kInternalSetPrototype);
+ CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
break;
@@ -1525,12 +1506,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
for (AccessorTable::Iterator it = accessor_table.begin();
it != accessor_table.end();
++it) {
- __ Push(Operand(rsp, 0)); // Duplicate receiver.
+ PushOperand(Operand(rsp, 0)); // Duplicate receiver.
VisitForStackValue(it->first);
EmitAccessor(it->second->getter);
EmitAccessor(it->second->setter);
- __ Push(Smi::FromInt(NONE));
- __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked);
+ PushOperand(Smi::FromInt(NONE));
+ CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
}
// Object literals have two parts. The "static" part on the left contains no
@@ -1547,17 +1528,17 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Expression* value = property->value();
if (!result_saved) {
- __ Push(rax); // Save result on the stack
+ PushOperand(rax); // Save result on the stack
result_saved = true;
}
- __ Push(Operand(rsp, 0)); // Duplicate receiver.
+ PushOperand(Operand(rsp, 0)); // Duplicate receiver.
if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
DCHECK(!property->is_computed_name());
VisitForStackValue(value);
DCHECK(property->emit_store());
- __ CallRuntime(Runtime::kInternalSetPrototype);
+ CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
} else {
@@ -1572,11 +1553,11 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::MATERIALIZED_LITERAL:
case ObjectLiteral::Property::COMPUTED:
if (property->emit_store()) {
- __ Push(Smi::FromInt(NONE));
- __ Push(Smi::FromInt(property->NeedsSetFunctionName()));
- __ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
+ PushOperand(Smi::FromInt(NONE));
+ PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
+ CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
} else {
- __ Drop(3);
+ DropOperands(3);
}
break;
@@ -1585,13 +1566,13 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
break;
case ObjectLiteral::Property::GETTER:
- __ Push(Smi::FromInt(NONE));
- __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
+ PushOperand(Smi::FromInt(NONE));
+ CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
break;
case ObjectLiteral::Property::SETTER:
- __ Push(Smi::FromInt(NONE));
- __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
+ PushOperand(Smi::FromInt(NONE));
+ CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
break;
}
}
@@ -1656,7 +1637,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
if (!result_saved) {
- __ Push(rax); // array literal
+ PushOperand(rax); // array literal
result_saved = true;
}
VisitForAccumulatorValue(subexpr);
@@ -1677,16 +1658,16 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
// (inclusive) and these elements gets appended to the array. Note that the
// number elements an iterable produces is unknown ahead of time.
if (array_index < length && result_saved) {
- __ Pop(rax);
+ PopOperand(rax);
result_saved = false;
}
for (; array_index < length; array_index++) {
Expression* subexpr = subexprs->at(array_index);
- __ Push(rax);
+ PushOperand(rax);
DCHECK(!subexpr->IsSpread());
VisitForStackValue(subexpr);
- __ CallRuntime(Runtime::kAppendElement);
+ CallRuntimeWithOperands(Runtime::kAppendElement);
PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
}
@@ -1727,10 +1708,10 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
property->obj()->AsSuperPropertyReference()->this_var());
VisitForAccumulatorValue(
property->obj()->AsSuperPropertyReference()->home_object());
- __ Push(result_register());
+ PushOperand(result_register());
if (expr->is_compound()) {
- __ Push(MemOperand(rsp, kPointerSize));
- __ Push(result_register());
+ PushOperand(MemOperand(rsp, kPointerSize));
+ PushOperand(result_register());
}
break;
case KEYED_SUPER_PROPERTY:
@@ -1739,11 +1720,11 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
VisitForStackValue(
property->obj()->AsSuperPropertyReference()->home_object());
VisitForAccumulatorValue(property->key());
- __ Push(result_register());
+ PushOperand(result_register());
if (expr->is_compound()) {
- __ Push(MemOperand(rsp, 2 * kPointerSize));
- __ Push(MemOperand(rsp, 2 * kPointerSize));
- __ Push(result_register());
+ PushOperand(MemOperand(rsp, 2 * kPointerSize));
+ PushOperand(MemOperand(rsp, 2 * kPointerSize));
+ PushOperand(result_register());
}
break;
case KEYED_PROPERTY: {
@@ -1789,7 +1770,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
}
Token::Value op = expr->binary_op();
- __ Push(rax); // Left operand goes on the stack.
+ PushOperand(rax); // Left operand goes on the stack.
VisitForAccumulatorValue(expr->value());
AccumulatorValueContext context(this);
@@ -1883,7 +1864,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
Operand(rbp, StandardFrameConstants::kContextOffset));
__ bind(&post_runtime);
- __ Pop(result_register());
+ PopOperand(result_register());
EmitReturnSequence();
__ bind(&resume);
@@ -1893,6 +1874,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
case Yield::kFinal: {
// Pop value from top-of-stack slot, box result into result register.
+ OperandStackDepthDecrement(1);
EmitCreateIteratorResult(true);
EmitUnwindAndReturn();
break;
@@ -1913,7 +1895,7 @@ void FullCodeGenerator::EmitGeneratorResume(
// rbx will hold the generator object until the activation has been resumed.
VisitForStackValue(generator);
VisitForAccumulatorValue(value);
- __ Pop(rbx);
+ PopOperand(rbx);
// Store input value into generator object.
__ movp(FieldOperand(rbx, JSGeneratorObject::kInputOffset),
@@ -1996,6 +1978,21 @@ void FullCodeGenerator::EmitGeneratorResume(
context()->Plug(result_register());
}
+void FullCodeGenerator::PushOperand(MemOperand operand) {
+ OperandStackDepthIncrement(1);
+ __ Push(operand);
+}
+
+void FullCodeGenerator::EmitOperandStackDepthCheck() {
+ if (FLAG_debug_code) {
+ int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp +
+ operand_stack_depth_ * kPointerSize;
+ __ movp(rax, rbp);
+ __ subp(rax, rsp);
+ __ cmpp(rax, Immediate(expected_diff));
+ __ Assert(equal, kUnexpectedStackDepth);
+ }
+}
void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
Label allocate, done_allocate;
@@ -2023,6 +2020,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetExpressionPosition(prop);
Literal* key = prop->key()->AsLiteral();
+ DCHECK(!key->value()->IsSmi());
DCHECK(!prop->IsSuperAccess());
__ Move(LoadDescriptor::NameRegister(), key->value());
@@ -2032,34 +2030,6 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
}
-void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
- // Stack: receiver, home_object
- SetExpressionPosition(prop);
- Literal* key = prop->key()->AsLiteral();
- DCHECK(!key->value()->IsSmi());
- DCHECK(prop->IsSuperAccess());
-
- __ Push(key->value());
- __ CallRuntime(Runtime::kLoadFromSuper);
-}
-
-
-void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
- SetExpressionPosition(prop);
- Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
- __ Move(LoadDescriptor::SlotRegister(),
- SmiFromSlot(prop->PropertyFeedbackSlot()));
- CallIC(ic);
-}
-
-
-void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
- // Stack: receiver, home_object, key.
- SetExpressionPosition(prop);
- __ CallRuntime(Runtime::kLoadKeyedFromSuper);
-}
-
-
void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
Token::Value op,
Expression* left,
@@ -2068,7 +2038,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
// stack (popped into rdx). Right operand is in rax but moved into
// rcx to make the shifts easier.
Label done, stub_call, smi_case;
- __ Pop(rdx);
+ PopOperand(rdx);
__ movp(rcx, rax);
__ orp(rax, rdx);
JumpPatchSite patch_site(masm_);
@@ -2126,9 +2096,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
Expression* value = property->value();
if (property->is_static()) {
- __ Push(Operand(rsp, kPointerSize)); // constructor
+ PushOperand(Operand(rsp, kPointerSize)); // constructor
} else {
- __ Push(Operand(rsp, 0)); // prototype
+ PushOperand(Operand(rsp, 0)); // prototype
}
EmitPropertyKey(property, lit->GetIdForProperty(i));
@@ -2152,19 +2122,19 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
case ObjectLiteral::Property::PROTOTYPE:
UNREACHABLE();
case ObjectLiteral::Property::COMPUTED:
- __ Push(Smi::FromInt(DONT_ENUM));
- __ Push(Smi::FromInt(property->NeedsSetFunctionName()));
- __ CallRuntime(Runtime::kDefineDataPropertyInLiteral);
+ PushOperand(Smi::FromInt(DONT_ENUM));
+ PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
+ CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
break;
case ObjectLiteral::Property::GETTER:
- __ Push(Smi::FromInt(DONT_ENUM));
- __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked);
+ PushOperand(Smi::FromInt(DONT_ENUM));
+ CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
break;
case ObjectLiteral::Property::SETTER:
- __ Push(Smi::FromInt(DONT_ENUM));
- __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked);
+ PushOperand(Smi::FromInt(DONT_ENUM));
+ CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
break;
default:
@@ -2175,7 +2145,7 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
- __ Pop(rdx);
+ PopOperand(rdx);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
CallIC(code, expr->BinaryOperationFeedbackId());
@@ -2199,10 +2169,10 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
break;
}
case NAMED_PROPERTY: {
- __ Push(rax); // Preserve value.
+ PushOperand(rax); // Preserve value.
VisitForAccumulatorValue(prop->obj());
__ Move(StoreDescriptor::ReceiverRegister(), rax);
- __ Pop(StoreDescriptor::ValueRegister()); // Restore value.
+ PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
__ Move(StoreDescriptor::NameRegister(),
prop->key()->AsLiteral()->value());
EmitLoadStoreICSlot(slot);
@@ -2210,7 +2180,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
break;
}
case NAMED_SUPER_PROPERTY: {
- __ Push(rax);
+ PushOperand(rax);
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
VisitForAccumulatorValue(
prop->obj()->AsSuperPropertyReference()->home_object());
@@ -2227,7 +2197,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
break;
}
case KEYED_SUPER_PROPERTY: {
- __ Push(rax);
+ PushOperand(rax);
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
VisitForStackValue(
prop->obj()->AsSuperPropertyReference()->home_object());
@@ -2247,12 +2217,12 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
break;
}
case KEYED_PROPERTY: {
- __ Push(rax); // Preserve value.
+ PushOperand(rax); // Preserve value.
VisitForStackValue(prop->obj());
VisitForAccumulatorValue(prop->key());
__ Move(StoreDescriptor::NameRegister(), rax);
- __ Pop(StoreDescriptor::ReceiverRegister());
- __ Pop(StoreDescriptor::ValueRegister()); // Restore value.
+ PopOperand(StoreDescriptor::ReceiverRegister());
+ PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
EmitLoadStoreICSlot(slot);
Handle<Code> ic =
CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
@@ -2384,7 +2354,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
DCHECK(prop->key()->IsLiteral());
__ Move(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value());
- __ Pop(StoreDescriptor::ReceiverRegister());
+ PopOperand(StoreDescriptor::ReceiverRegister());
EmitLoadStoreICSlot(expr->AssignmentSlot());
CallStoreIC();
@@ -2401,10 +2371,11 @@ void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
Literal* key = prop->key()->AsLiteral();
DCHECK(key != NULL);
- __ Push(key->value());
- __ Push(rax);
- __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
- : Runtime::kStoreToSuper_Sloppy));
+ PushOperand(key->value());
+ PushOperand(rax);
+ CallRuntimeWithOperands(is_strict(language_mode())
+ ? Runtime::kStoreToSuper_Strict
+ : Runtime::kStoreToSuper_Sloppy);
}
@@ -2414,17 +2385,17 @@ void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
// stack : receiver ('this'), home_object, key
DCHECK(prop != NULL);
- __ Push(rax);
- __ CallRuntime((is_strict(language_mode())
- ? Runtime::kStoreKeyedToSuper_Strict
- : Runtime::kStoreKeyedToSuper_Sloppy));
+ PushOperand(rax);
+ CallRuntimeWithOperands(is_strict(language_mode())
+ ? Runtime::kStoreKeyedToSuper_Strict
+ : Runtime::kStoreKeyedToSuper_Sloppy);
}
void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a keyed store IC.
- __ Pop(StoreDescriptor::NameRegister()); // Key.
- __ Pop(StoreDescriptor::ReceiverRegister());
+ PopOperand(StoreDescriptor::NameRegister()); // Key.
+ PopOperand(StoreDescriptor::ReceiverRegister());
DCHECK(StoreDescriptor::ValueRegister().is(rax));
Handle<Code> ic =
CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
@@ -2459,7 +2430,7 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
VisitForStackValue(expr->obj());
VisitForAccumulatorValue(expr->key());
__ Move(LoadDescriptor::NameRegister(), rax);
- __ Pop(LoadDescriptor::ReceiverRegister());
+ PopOperand(LoadDescriptor::ReceiverRegister());
EmitKeyedPropertyLoad(expr);
} else {
VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
@@ -2494,7 +2465,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
}
// Push undefined as receiver. This is patched in the Call builtin if it
// is a sloppy mode method.
- __ Push(isolate()->factory()->undefined_value());
+ PushOperand(isolate()->factory()->undefined_value());
convert_mode = ConvertReceiverMode::kNullOrUndefined;
} else {
// Load the function from the receiver.
@@ -2504,7 +2475,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
EmitNamedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
// Push the target function under the receiver.
- __ Push(Operand(rsp, 0));
+ PushOperand(Operand(rsp, 0));
__ movp(Operand(rsp, kPointerSize), rax);
convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
}
@@ -2526,10 +2497,10 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
VisitForStackValue(super_ref->home_object());
VisitForAccumulatorValue(super_ref->this_var());
- __ Push(rax);
- __ Push(rax);
- __ Push(Operand(rsp, kPointerSize * 2));
- __ Push(key->value());
+ PushOperand(rax);
+ PushOperand(rax);
+ PushOperand(Operand(rsp, kPointerSize * 2));
+ PushOperand(key->value());
// Stack here:
// - home_object
@@ -2537,7 +2508,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
// - this (receiver) <-- LoadFromSuper will pop here and below.
// - home_object
// - key
- __ CallRuntime(Runtime::kLoadFromSuper);
+ CallRuntimeWithOperands(Runtime::kLoadFromSuper);
// Replace home_object with target function.
__ movp(Operand(rsp, kPointerSize), rax);
@@ -2565,7 +2536,7 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
// Push the target function under the receiver.
- __ Push(Operand(rsp, 0));
+ PushOperand(Operand(rsp, 0));
__ movp(Operand(rsp, kPointerSize), rax);
EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
@@ -2583,9 +2554,9 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
VisitForStackValue(super_ref->home_object());
VisitForAccumulatorValue(super_ref->this_var());
- __ Push(rax);
- __ Push(rax);
- __ Push(Operand(rsp, kPointerSize * 2));
+ PushOperand(rax);
+ PushOperand(rax);
+ PushOperand(Operand(rsp, kPointerSize * 2));
VisitForStackValue(prop->key());
// Stack here:
@@ -2594,7 +2565,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
// - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
// - home_object
// - key
- __ CallRuntime(Runtime::kLoadKeyedFromSuper);
+ CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
// Replace home_object with target function.
__ movp(Operand(rsp, kPointerSize), rax);
@@ -2632,6 +2603,7 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
// Don't assign a type feedback id to the IC, since type feedback is provided
// by the vector above.
CallIC(ic);
+ OperandStackDepthDecrement(arg_count + 1);
RecordJSReturnSite(expr);
@@ -2678,8 +2650,8 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
// the object holding it (returned in rdx).
__ Push(callee->name());
__ CallRuntime(Runtime::kLoadLookupSlotForCall);
- __ Push(rax); // Function.
- __ Push(rdx); // Receiver.
+ PushOperand(rax); // Function.
+ PushOperand(rdx); // Receiver.
PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
// If fast case code has been generated, emit code to push the function
@@ -2699,6 +2671,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
} else {
VisitForStackValue(callee);
// refEnv.WithBaseObject()
+ OperandStackDepthIncrement(1);
__ PushRoot(Heap::kUndefinedValueRootIndex);
}
}
@@ -2733,6 +2706,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
__ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
expr->tail_call_mode()),
RelocInfo::CODE_TARGET);
+ OperandStackDepthDecrement(arg_count + 1);
RecordJSReturnSite(expr);
// Restore context register.
__ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
@@ -2773,6 +2747,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
CallConstructStub stub(isolate());
__ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
+ OperandStackDepthDecrement(arg_count + 1);
PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
// Restore context register.
__ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
@@ -2791,7 +2766,7 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
__ AssertFunction(result_register());
__ movp(result_register(),
FieldOperand(result_register(), HeapObject::kMapOffset));
- __ Push(FieldOperand(result_register(), Map::kPrototypeOffset));
+ PushOperand(FieldOperand(result_register(), Map::kPrototypeOffset));
// Push the arguments ("left-to-right") on the stack.
ZoneList<Expression*>* args = expr->arguments();
@@ -2813,6 +2788,7 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
__ movp(rdi, Operand(rsp, arg_count * kPointerSize));
__ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
+ OperandStackDepthDecrement(arg_count + 1);
RecordJSReturnSite(expr);
@@ -3034,8 +3010,8 @@ void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
VisitForStackValue(args->at(0)); // index
VisitForStackValue(args->at(1)); // value
VisitForAccumulatorValue(args->at(2)); // string
- __ Pop(value);
- __ Pop(index);
+ PopOperand(value);
+ PopOperand(index);
if (FLAG_debug_code) {
__ Check(__ CheckSmi(value), kNonSmiValue);
@@ -3067,8 +3043,8 @@ void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
VisitForStackValue(args->at(0)); // index
VisitForStackValue(args->at(1)); // value
VisitForAccumulatorValue(args->at(2)); // string
- __ Pop(value);
- __ Pop(index);
+ PopOperand(value);
+ PopOperand(index);
if (FLAG_debug_code) {
__ Check(__ CheckSmi(value), kNonSmiValue);
@@ -3136,7 +3112,7 @@ void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) {
Register index = rax;
Register result = rdx;
- __ Pop(object);
+ PopOperand(object);
Label need_conversion;
Label index_out_of_range;
@@ -3183,7 +3159,7 @@ void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
Register scratch = rdx;
Register result = rax;
- __ Pop(object);
+ PopOperand(object);
Label need_conversion;
Label index_out_of_range;
@@ -3233,6 +3209,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) {
// Call the target.
__ Set(rax, argc);
__ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
+ OperandStackDepthDecrement(argc + 1);
// Restore context register.
__ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
// Discard the function left on TOS.
@@ -3320,7 +3297,7 @@ void FullCodeGenerator::EmitCreateIterResultObject(CallRuntime* expr) {
__ jmp(&done, Label::kNear);
__ bind(&runtime);
- __ CallRuntime(Runtime::kCreateIterResultObject);
+ CallRuntimeWithOperands(Runtime::kCreateIterResultObject);
__ bind(&done);
context()->Plug(rax);
@@ -3329,6 +3306,7 @@ void FullCodeGenerator::EmitCreateIterResultObject(CallRuntime* expr) {
void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
// Push the builtins object as receiver.
+ OperandStackDepthIncrement(1);
__ PushRoot(Heap::kUndefinedValueRootIndex);
__ LoadNativeContextSlot(expr->context_index(), rax);
@@ -3344,6 +3322,7 @@ void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
__ Set(rax, arg_count);
__ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
RelocInfo::CODE_TARGET);
+ OperandStackDepthDecrement(arg_count + 1);
}
@@ -3357,7 +3336,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
EmitLoadJSRuntimeFunction(expr);
// Push the target function under the receiver.
- __ Push(Operand(rsp, 0));
+ PushOperand(Operand(rsp, 0));
__ movp(Operand(rsp, kPointerSize), rax);
// Push the arguments ("left-to-right").
@@ -3392,6 +3371,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
// Call the C runtime.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
__ CallRuntime(function, arg_count);
+ OperandStackDepthDecrement(arg_count);
context()->Plug(rax);
}
}
@@ -3409,9 +3389,9 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
if (property != NULL) {
VisitForStackValue(property->obj());
VisitForStackValue(property->key());
- __ CallRuntime(is_strict(language_mode())
- ? Runtime::kDeleteProperty_Strict
- : Runtime::kDeleteProperty_Sloppy);
+ CallRuntimeWithOperands(is_strict(language_mode())
+ ? Runtime::kDeleteProperty_Strict
+ : Runtime::kDeleteProperty_Sloppy);
context()->Plug(rax);
} else if (proxy != NULL) {
Variable* var = proxy->var();
@@ -3478,6 +3458,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
&materialize_false,
&materialize_true,
&materialize_true);
+ if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
__ bind(&materialize_true);
PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
if (context()->IsAccumulatorValue()) {
@@ -3533,7 +3514,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
} else {
// Reserve space for result of postfix operation.
if (expr->is_postfix() && !context()->IsEffect()) {
- __ Push(Smi::FromInt(0));
+ PushOperand(Smi::FromInt(0));
}
switch (assign_type) {
case NAMED_PROPERTY: {
@@ -3547,9 +3528,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
VisitForAccumulatorValue(
prop->obj()->AsSuperPropertyReference()->home_object());
- __ Push(result_register());
- __ Push(MemOperand(rsp, kPointerSize));
- __ Push(result_register());
+ PushOperand(result_register());
+ PushOperand(MemOperand(rsp, kPointerSize));
+ PushOperand(result_register());
EmitNamedSuperPropertyLoad(prop);
break;
}
@@ -3559,10 +3540,10 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
VisitForStackValue(
prop->obj()->AsSuperPropertyReference()->home_object());
VisitForAccumulatorValue(prop->key());
- __ Push(result_register());
- __ Push(MemOperand(rsp, 2 * kPointerSize));
- __ Push(MemOperand(rsp, 2 * kPointerSize));
- __ Push(result_register());
+ PushOperand(result_register());
+ PushOperand(MemOperand(rsp, 2 * kPointerSize));
+ PushOperand(MemOperand(rsp, 2 * kPointerSize));
+ PushOperand(result_register());
EmitKeyedSuperPropertyLoad(prop);
break;
}
@@ -3651,7 +3632,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
// of the stack.
switch (assign_type) {
case VARIABLE:
- __ Push(rax);
+ PushOperand(rax);
break;
case NAMED_PROPERTY:
__ movp(Operand(rsp, kPointerSize), rax);
@@ -3711,7 +3692,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
case NAMED_PROPERTY: {
__ Move(StoreDescriptor::NameRegister(),
prop->key()->AsLiteral()->value());
- __ Pop(StoreDescriptor::ReceiverRegister());
+ PopOperand(StoreDescriptor::ReceiverRegister());
EmitLoadStoreICSlot(expr->CountSlot());
CallStoreIC();
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
@@ -3747,8 +3728,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
break;
}
case KEYED_PROPERTY: {
- __ Pop(StoreDescriptor::NameRegister());
- __ Pop(StoreDescriptor::ReceiverRegister());
+ PopOperand(StoreDescriptor::NameRegister());
+ PopOperand(StoreDescriptor::ReceiverRegister());
Handle<Code> ic =
CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
EmitLoadStoreICSlot(expr->CountSlot());
@@ -3869,7 +3850,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
switch (op) {
case Token::IN:
VisitForStackValue(expr->right());
- __ CallRuntime(Runtime::kHasProperty);
+ CallRuntimeWithOperands(Runtime::kHasProperty);
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
__ CompareRoot(rax, Heap::kTrueValueRootIndex);
Split(equal, if_true, if_false, fall_through);
@@ -3877,7 +3858,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
case Token::INSTANCEOF: {
VisitForAccumulatorValue(expr->right());
- __ Pop(rdx);
+ PopOperand(rdx);
InstanceOfStub stub(isolate());
__ CallStub(&stub);
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
@@ -3889,7 +3870,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
default: {
VisitForAccumulatorValue(expr->right());
Condition cc = CompareIC::ComputeCondition(op);
- __ Pop(rdx);
+ PopOperand(rdx);
bool inline_smi_code = ShouldInlineSmiCase(op);
JumpPatchSite patch_site(masm_);
@@ -3982,15 +3963,15 @@ void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
// as their closure, not the anonymous closure containing the global
// code.
__ movp(rax, NativeContextOperand());
- __ Push(ContextOperand(rax, Context::CLOSURE_INDEX));
+ PushOperand(ContextOperand(rax, Context::CLOSURE_INDEX));
} else if (closure_scope->is_eval_scope()) {
// Contexts created by a call to eval have the same closure as the
// context calling eval, not the anonymous closure containing the eval
// code. Fetch it from the context.
- __ Push(ContextOperand(rsi, Context::CLOSURE_INDEX));
+ PushOperand(ContextOperand(rsi, Context::CLOSURE_INDEX));
} else {
DCHECK(closure_scope->is_function_scope());
- __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
+ PushOperand(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
}
}
@@ -4006,7 +3987,7 @@ void FullCodeGenerator::EnterFinallyBlock() {
ExternalReference pending_message_obj =
ExternalReference::address_of_pending_message_obj(isolate());
__ Load(rdx, pending_message_obj);
- __ Push(rdx);
+ PushOperand(rdx);
ClearPendingMessage();
}
@@ -4015,7 +3996,7 @@ void FullCodeGenerator::EnterFinallyBlock() {
void FullCodeGenerator::ExitFinallyBlock() {
DCHECK(!result_register().is(rdx));
// Restore pending message from stack.
- __ Pop(rdx);
+ PopOperand(rdx);
ExternalReference pending_message_obj =
ExternalReference::address_of_pending_message_obj(isolate());
__ Store(pending_message_obj, rdx);
« no previous file with comments | « src/full-codegen/ppc/full-codegen-ppc.cc ('k') | src/full-codegen/x87/full-codegen-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698