Commit b3de78c1 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: [fullcodegen] Implement operand stack depth tracking.

Port 38915ed7

Original commit message:
    This implements a mechanism to track the exact depth of the operand
    stack in full-codegen for every sub-expression visitation. So far we
    only tracked the depth at statement level, but not at expression level.
    With the introduction of do-expressions it will be possible to construct
    local control flow (i.e. break, continue and friends) that target labels
    at an arbitrary operand stack depth, making this tracking a prerequisite
    for full do-expression support.

R=mstarzinger@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=v8:4755,v8:4488
LOG=n

Review URL: https://codereview.chromium.org/1729613002

Cr-Commit-Position: refs/heads/master@{#34227}
parent 1353b37d
......@@ -136,6 +136,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 > 0) {
if (locals_count >= 128) {
Label ok;
......@@ -460,7 +461,7 @@ void FullCodeGenerator::EmitReturnSequence() {
void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
DCHECK(var->IsStackAllocated() || var->IsContextSlot());
codegen()->GetVar(result_register(), var);
__ push(result_register());
codegen()->PushOperand(result_register());
}
......@@ -476,7 +477,7 @@ void FullCodeGenerator::AccumulatorValueContext::Plug(
void FullCodeGenerator::StackValueContext::Plug(
Heap::RootListIndex index) const {
__ LoadRoot(result_register(), index);
__ push(result_register());
codegen()->PushOperand(result_register());
}
......@@ -508,7 +509,7 @@ void FullCodeGenerator::AccumulatorValueContext::Plug(
void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
// Immediates cannot be pushed directly.
__ mov(result_register(), Operand(lit));
__ push(result_register());
codegen()->PushOperand(result_register());
}
......@@ -543,7 +544,7 @@ void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
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);
__ StoreP(reg, MemOperand(sp, 0));
}
......@@ -576,7 +577,7 @@ void FullCodeGenerator::StackValueContext::Plug(
__ bind(materialize_false);
__ LoadRoot(ip, Heap::kFalseValueRootIndex);
__ bind(&done);
__ push(ip);
codegen()->PushOperand(ip);
}
......@@ -598,7 +599,7 @@ void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
Heap::RootListIndex value_root_index =
flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
__ LoadRoot(ip, value_root_index);
__ push(ip);
codegen()->PushOperand(ip);
}
......@@ -825,11 +826,11 @@ void FullCodeGenerator::VisitFunctionDeclaration(
case VariableLocation::LOOKUP: {
Comment cmnt(masm_, "[ FunctionDeclaration");
__ mov(r5, Operand(variable->name()));
__ Push(r5);
PushOperand(r5);
// Push initial value for function declaration.
VisitForStackValue(declaration->fun());
__ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
__ CallRuntime(Runtime::kDeclareLookupSlot);
PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
break;
}
}
......@@ -927,7 +928,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) {
__ b(nested_statement.break_label());
} else {
......@@ -961,6 +962,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.
......@@ -1127,7 +1129,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Remove the pointers stored on the stack.
__ bind(loop_statement.break_label());
__ Drop(5);
DropOperands(5);
// Exit and decrement the loop depth.
PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
......@@ -1397,7 +1399,7 @@ void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
Expression* expression = (property == NULL) ? NULL : property->value();
if (expression == NULL) {
__ LoadRoot(r4, Heap::kNullValueRootIndex);
__ push(r4);
PushOperand(r4);
} else {
VisitForStackValue(expression);
if (NeedsHomeObject(expression)) {
......@@ -1442,7 +1444,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Literal* key = property->key()->AsLiteral();
Expression* value = property->value();
if (!result_saved) {
__ push(r3); // Save result on stack
PushOperand(r3); // Save result on stack
result_saved = true;
}
switch (property->kind()) {
......@@ -1474,7 +1476,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
}
// Duplicate receiver on stack.
__ LoadP(r3, MemOperand(sp));
__ push(r3);
PushOperand(r3);
VisitForStackValue(key);
VisitForStackValue(value);
if (property->emit_store()) {
......@@ -1482,19 +1484,19 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
EmitSetHomeObject(value, 2, property->GetSlot());
}
__ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); // PropertyAttributes
__ push(r3);
__ CallRuntime(Runtime::kSetProperty);
PushOperand(r3);
CallRuntimeWithOperands(Runtime::kSetProperty);
} else {
__ Drop(3);
DropOperands(3);
}
break;
case ObjectLiteral::Property::PROTOTYPE:
// Duplicate receiver on stack.
__ LoadP(r3, MemOperand(sp));
__ push(r3);
PushOperand(r3);
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
break;
......@@ -1516,13 +1518,13 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
for (AccessorTable::Iterator it = accessor_table.begin();
it != accessor_table.end(); ++it) {
__ LoadP(r3, MemOperand(sp)); // Duplicate receiver.
__ push(r3);
PushOperand(r3);
VisitForStackValue(it->first);
EmitAccessor(it->second->getter);
EmitAccessor(it->second->setter);
__ LoadSmiLiteral(r3, Smi::FromInt(NONE));
__ push(r3);
__ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked);
PushOperand(r3);
CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
}
// Object literals have two parts. The "static" part on the left contains no
......@@ -1539,18 +1541,18 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Expression* value = property->value();
if (!result_saved) {
__ push(r3); // Save result on the stack
PushOperand(r3); // Save result on the stack
result_saved = true;
}
__ LoadP(r3, MemOperand(sp)); // Duplicate receiver.
__ push(r3);
PushOperand(r3);
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 {
......@@ -1565,11 +1567,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;
......@@ -1578,13 +1580,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;
}
}
......@@ -1649,7 +1651,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
if (!result_saved) {
__ push(r3);
PushOperand(r3);
result_saved = true;
}
VisitForAccumulatorValue(subexpr);
......@@ -1671,16 +1673,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(r3);
PopOperand(r3);
result_saved = false;
}
for (; array_index < length; array_index++) {
Expression* subexpr = subexprs->at(array_index);
__ Push(r3);
PushOperand(r3);
DCHECK(!subexpr->IsSpread());
VisitForStackValue(subexpr);
__ CallRuntime(Runtime::kAppendElement);
CallRuntimeWithOperands(Runtime::kAppendElement);
PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
}
......@@ -1721,11 +1723,11 @@ 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()) {
const Register scratch = r4;
__ LoadP(scratch, MemOperand(sp, kPointerSize));
__ Push(scratch, result_register());
PushOperands(scratch, result_register());
}
break;
case KEYED_SUPER_PROPERTY: {
......@@ -1736,11 +1738,11 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
property->obj()->AsSuperPropertyReference()->home_object());
__ mr(scratch, result_register());
VisitForAccumulatorValue(property->key());
__ Push(scratch, result_register());
PushOperands(scratch, result_register());
if (expr->is_compound()) {
const Register scratch1 = r5;
__ LoadP(scratch1, MemOperand(sp, 2 * kPointerSize));
__ Push(scratch1, scratch, result_register());
PushOperands(scratch1, scratch, result_register());
}
break;
}
......@@ -1788,7 +1790,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
}
Token::Value op = expr->binary_op();
__ push(r3); // Left operand goes on the stack.
PushOperand(r3); // Left operand goes on the stack.
VisitForAccumulatorValue(expr->value());
AccumulatorValueContext context(this);
......@@ -1880,7 +1882,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
__ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
__ bind(&post_runtime);
__ pop(result_register());
PopOperand(result_register());
EmitReturnSequence();
__ bind(&resume);
......@@ -1890,6 +1892,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;
......@@ -1910,7 +1913,7 @@ void FullCodeGenerator::EmitGeneratorResume(
// r4 will hold the generator object until the activation has been resumed.
VisitForStackValue(generator);
VisitForAccumulatorValue(value);
__ pop(r4);
PopOperand(r4);
// Store input value into generator object.
__ StoreP(result_register(),
......@@ -2013,6 +2016,37 @@ void FullCodeGenerator::EmitGeneratorResume(
context()->Plug(result_register());
}
void FullCodeGenerator::PushOperands(Register reg1, Register reg2) {
OperandStackDepthIncrement(2);
__ Push(reg1, reg2);
}
void FullCodeGenerator::PushOperands(Register reg1, Register reg2,
Register reg3) {
OperandStackDepthIncrement(3);
__ Push(reg1, reg2, reg3);
}
void FullCodeGenerator::PushOperands(Register reg1, Register reg2,
Register reg3, Register reg4) {
OperandStackDepthIncrement(4);
__ Push(reg1, reg2, reg3, reg4);
}
void FullCodeGenerator::PopOperands(Register reg1, Register reg2) {
OperandStackDepthDecrement(2);
__ Pop(reg1, reg2);
}
void FullCodeGenerator::EmitOperandStackDepthCheck() {
if (FLAG_debug_code) {
int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp +
operand_stack_depth_ * kPointerSize;
__ sub(r3, fp, sp);
__ cmpi(r3, Operand(expected_diff));
__ Assert(eq, kUnexpectedStackDepth);
}
}
void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
Label allocate, done_allocate;
......@@ -2062,7 +2096,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
// Get the arguments.
Register left = r4;
Register right = r3;
__ pop(left);
PopOperand(left);
// Perform combined smi check on both operands.
__ orx(scratch1, left, right);
......@@ -2186,7 +2220,7 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
} else {
__ LoadP(scratch, MemOperand(sp, 0)); // prototype
}
__ push(scratch);
PushOperand(scratch);
EmitPropertyKey(property, lit->GetIdForProperty(i));
// The static prototype property is read only. We handle the non computed
......@@ -2209,19 +2243,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:
......@@ -2232,7 +2266,7 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ pop(r4);
PopOperand(r4);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
CallIC(code, expr->BinaryOperationFeedbackId());
......@@ -2256,10 +2290,10 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
break;
}
case NAMED_PROPERTY: {
__ push(r3); // Preserve value.
PushOperand(r3); // Preserve value.
VisitForAccumulatorValue(prop->obj());
__ Move(StoreDescriptor::ReceiverRegister(), r3);
__ pop(StoreDescriptor::ValueRegister()); // Restore value.
PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
__ mov(StoreDescriptor::NameRegister(),
Operand(prop->key()->AsLiteral()->value()));
EmitLoadStoreICSlot(slot);
......@@ -2267,7 +2301,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
break;
}
case NAMED_SUPER_PROPERTY: {
__ Push(r3);
PushOperand(r3);
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
VisitForAccumulatorValue(
prop->obj()->AsSuperPropertyReference()->home_object());
......@@ -2284,7 +2318,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
break;
}
case KEYED_SUPER_PROPERTY: {
__ Push(r3);
PushOperand(r3);
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
VisitForStackValue(
prop->obj()->AsSuperPropertyReference()->home_object());
......@@ -2304,12 +2338,12 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
break;
}
case KEYED_PROPERTY: {
__ push(r3); // Preserve value.
PushOperand(r3); // Preserve value.
VisitForStackValue(prop->obj());
VisitForAccumulatorValue(prop->key());
__ Move(StoreDescriptor::NameRegister(), r3);
__ Pop(StoreDescriptor::ValueRegister(),
StoreDescriptor::ReceiverRegister());
PopOperands(StoreDescriptor::ValueRegister(),
StoreDescriptor::ReceiverRegister());
EmitLoadStoreICSlot(slot);
Handle<Code> ic =
CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
......@@ -2447,7 +2481,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
__ mov(StoreDescriptor::NameRegister(),
Operand(prop->key()->AsLiteral()->value()));
__ pop(StoreDescriptor::ReceiverRegister());
PopOperand(StoreDescriptor::ReceiverRegister());
EmitLoadStoreICSlot(expr->AssignmentSlot());
CallStoreIC();
......@@ -2464,10 +2498,11 @@ void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
Literal* key = prop->key()->AsLiteral();
DCHECK(key != NULL);
__ Push(key->value());
__ Push(r3);
__ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
: Runtime::kStoreToSuper_Sloppy));
PushOperand(key->value());
PushOperand(r3);
CallRuntimeWithOperands((is_strict(language_mode())
? Runtime::kStoreToSuper_Strict
: Runtime::kStoreToSuper_Sloppy));
}
......@@ -2477,16 +2512,17 @@ void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
// stack : receiver ('this'), home_object, key
DCHECK(prop != NULL);
__ Push(r3);
__ CallRuntime((is_strict(language_mode())
? Runtime::kStoreKeyedToSuper_Strict
: Runtime::kStoreKeyedToSuper_Sloppy));
PushOperand(r3);
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::ReceiverRegister(), StoreDescriptor::NameRegister());
PopOperands(StoreDescriptor::ReceiverRegister(),
StoreDescriptor::NameRegister());
DCHECK(StoreDescriptor::ValueRegister().is(r3));
Handle<Code> ic =
......@@ -2521,7 +2557,7 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
VisitForStackValue(expr->obj());
VisitForAccumulatorValue(expr->key());
__ Move(LoadDescriptor::NameRegister(), r3);
__ pop(LoadDescriptor::ReceiverRegister());
PopOperand(LoadDescriptor::ReceiverRegister());
EmitKeyedPropertyLoad(expr);
} else {
VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
......@@ -2557,7 +2593,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
// Push undefined as receiver. This is patched in the method prologue if it
// is a sloppy mode method.
__ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
__ push(r0);
PushOperand(r0);
convert_mode = ConvertReceiverMode::kNullOrUndefined;
} else {
// Load the function from the receiver.
......@@ -2568,7 +2604,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
// Push the target function under the receiver.
__ LoadP(r0, MemOperand(sp, 0));
__ push(r0);
PushOperand(r0);
__ StoreP(r3, MemOperand(sp, kPointerSize));
convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
}
......@@ -2592,8 +2628,8 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
VisitForAccumulatorValue(super_ref->home_object());
__ mr(scratch, r3);
VisitForAccumulatorValue(super_ref->this_var());
__ Push(scratch, r3, r3, scratch);
__ Push(key->value());
PushOperands(scratch, r3, r3, scratch);
PushOperand(key->value());
// Stack here:
// - home_object
......@@ -2601,7 +2637,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.
__ StoreP(r3, MemOperand(sp, kPointerSize));
......@@ -2629,7 +2665,7 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) {
// Push the target function under the receiver.
__ LoadP(ip, MemOperand(sp, 0));
__ push(ip);
PushOperand(ip);
__ StoreP(r3, MemOperand(sp, kPointerSize));
EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
......@@ -2649,7 +2685,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
VisitForAccumulatorValue(super_ref->home_object());
__ mr(scratch, r3);
VisitForAccumulatorValue(super_ref->this_var());
__ Push(scratch, r3, r3, scratch);
PushOperands(scratch, r3, r3, scratch);
VisitForStackValue(prop->key());
// Stack here:
......@@ -2658,7 +2694,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.
__ StoreP(r3, MemOperand(sp, kPointerSize));
......@@ -2696,6 +2732,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);
// Restore context register.
......@@ -2742,7 +2779,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
// the object holding it (returned in r4).
__ Push(callee->name());
__ CallRuntime(Runtime::kLoadLookupSlotForCall);
__ Push(r3, r4); // Function, receiver.
PushOperands(r3, r4); // Function, receiver.
PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
// If fast case code has been generated, emit code to push the function
......@@ -2764,7 +2801,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
VisitForStackValue(callee);
// refEnv.WithBaseObject()
__ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
__ push(r5); // Reserved receiver slot.
PushOperand(r5); // Reserved receiver slot.
}
}
......@@ -2801,6 +2838,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.
__ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
......@@ -2841,6 +2879,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.
__ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
......@@ -2861,7 +2900,7 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
FieldMemOperand(result_register(), HeapObject::kMapOffset));
__ LoadP(result_register(),
FieldMemOperand(result_register(), Map::kPrototypeOffset));
__ Push(result_register());
PushOperand(result_register());
// Push the arguments ("left-to-right") on the stack.
ZoneList<Expression*>* args = expr->arguments();
......@@ -2883,6 +2922,7 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
__ LoadP(r4, MemOperand(sp, arg_count * kPointerSize));
__ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
OperandStackDepthDecrement(arg_count + 1);
RecordJSReturnSite(expr);
......@@ -3104,7 +3144,7 @@ void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
VisitForStackValue(args->at(0)); // index
VisitForStackValue(args->at(1)); // value
VisitForAccumulatorValue(args->at(2)); // string
__ Pop(index, value);
PopOperands(index, value);
if (FLAG_debug_code) {
__ TestIfSmi(value, r0);
......@@ -3136,7 +3176,7 @@ void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
VisitForStackValue(args->at(0)); // index
VisitForStackValue(args->at(1)); // value
VisitForAccumulatorValue(args->at(2)); // string
__ Pop(index, value);
PopOperands(index, value);
if (FLAG_debug_code) {
__ TestIfSmi(value, r0);
......@@ -3202,7 +3242,7 @@ void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) {
Register index = r3;
Register result = r6;
__ pop(object);
PopOperand(object);
Label need_conversion;
Label index_out_of_range;
......@@ -3244,7 +3284,7 @@ void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
Register scratch = r6;
Register result = r3;
__ pop(object);
PopOperand(object);
Label need_conversion;
Label index_out_of_range;
......@@ -3289,6 +3329,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) {
// Call the target.
__ mov(r3, Operand(argc));
__ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
OperandStackDepthDecrement(argc + 1);
// Restore context register.
__ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
// Discard the function left on TOS.
......@@ -3375,7 +3416,7 @@ void FullCodeGenerator::EmitCreateIterResultObject(CallRuntime* expr) {
__ b(&done);
__ bind(&runtime);
__ CallRuntime(Runtime::kCreateIterResultObject);
CallRuntimeWithOperands(Runtime::kCreateIterResultObject);
__ bind(&done);
context()->Plug(r3);
......@@ -3385,7 +3426,7 @@ void FullCodeGenerator::EmitCreateIterResultObject(CallRuntime* expr) {
void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
// Push undefined as the receiver.
__ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
__ push(r3);
PushOperand(r3);
__ LoadNativeContextSlot(expr->context_index(), r3);
}
......@@ -3400,6 +3441,7 @@ void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
__ mov(r3, Operand(arg_count));
__ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
RelocInfo::CODE_TARGET);
OperandStackDepthDecrement(arg_count + 1);
}
......@@ -3413,7 +3455,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
// Push the target function under the receiver.
__ LoadP(ip, MemOperand(sp, 0));
__ push(ip);
PushOperand(ip);
__ StoreP(r3, MemOperand(sp, kPointerSize));
// Push the arguments ("left-to-right").
......@@ -3449,6 +3491,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
// Call the C runtime function.
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
__ CallRuntime(expr->function(), arg_count);
OperandStackDepthDecrement(arg_count);
context()->Plug(r3);
}
}
......@@ -3466,9 +3509,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(r3);
} else if (proxy != NULL) {
Variable* var = proxy->var();
......@@ -3530,6 +3573,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
Label materialize_true, materialize_false, done;
VisitForControl(expr->expression(), &materialize_false,
&materialize_true, &materialize_true);
if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
__ bind(&materialize_true);
PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
__ LoadRoot(r3, Heap::kTrueValueRootIndex);
......@@ -3580,7 +3624,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
// Reserve space for result of postfix operation.
if (expr->is_postfix() && !context()->IsEffect()) {
__ LoadSmiLiteral(ip, Smi::FromInt(0));
__ push(ip);
PushOperand(ip);
}
switch (assign_type) {
case NAMED_PROPERTY: {
......@@ -3595,10 +3639,10 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
VisitForAccumulatorValue(
prop->obj()->AsSuperPropertyReference()->home_object());
__ Push(result_register());
PushOperand(result_register());
const Register scratch = r4;
__ LoadP(scratch, MemOperand(sp, kPointerSize));
__ Push(scratch, result_register());
PushOperands(scratch, result_register());
EmitNamedSuperPropertyLoad(prop);
break;
}
......@@ -3611,9 +3655,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
const Register scratch1 = r5;
__ mr(scratch, result_register());
VisitForAccumulatorValue(prop->key());
__ Push(scratch, result_register());
PushOperands(scratch, result_register());
__ LoadP(scratch1, MemOperand(sp, 2 * kPointerSize));
__ Push(scratch1, scratch, result_register());
PushOperands(scratch1, scratch, result_register());
EmitKeyedSuperPropertyLoad(prop);
break;
}
......@@ -3700,7 +3744,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
// of the stack.
switch (assign_type) {
case VARIABLE:
__ push(r3);
PushOperand(r3);
break;
case NAMED_PROPERTY:
__ StoreP(r3, MemOperand(sp, kPointerSize));
......@@ -3758,7 +3802,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
case NAMED_PROPERTY: {
__ mov(StoreDescriptor::NameRegister(),
Operand(prop->key()->AsLiteral()->value()));
__ pop(StoreDescriptor::ReceiverRegister());
PopOperand(StoreDescriptor::ReceiverRegister());
EmitLoadStoreICSlot(expr->CountSlot());
CallStoreIC();
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
......@@ -3794,8 +3838,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
break;
}
case KEYED_PROPERTY: {
__ Pop(StoreDescriptor::ReceiverRegister(),
StoreDescriptor::NameRegister());
PopOperands(StoreDescriptor::ReceiverRegister(),
StoreDescriptor::NameRegister());
Handle<Code> ic =
CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
EmitLoadStoreICSlot(expr->CountSlot());
......@@ -3919,7 +3963,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(r3, Heap::kTrueValueRootIndex);
Split(eq, if_true, if_false, fall_through);
......@@ -3927,7 +3971,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
case Token::INSTANCEOF: {
VisitForAccumulatorValue(expr->right());
__ pop(r4);
PopOperand(r4);
InstanceOfStub stub(isolate());
__ CallStub(&stub);
PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
......@@ -3939,7 +3983,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
default: {
VisitForAccumulatorValue(expr->right());
Condition cond = CompareIC::ComputeCondition(op);
__ pop(r4);
PopOperand(r4);
bool inline_smi_code = ShouldInlineSmiCase(op);
JumpPatchSite patch_site(masm_);
......@@ -4036,7 +4080,7 @@ void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
DCHECK(closure_scope->is_function_scope());
__ LoadP(ip, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
}
__ push(ip);
PushOperand(ip);
}
......@@ -4050,7 +4094,7 @@ void FullCodeGenerator::EnterFinallyBlock() {
ExternalReference::address_of_pending_message_obj(isolate());
__ mov(ip, Operand(pending_message_obj));
__ LoadP(r4, MemOperand(ip));
__ push(r4);
PushOperand(r4);
ClearPendingMessage();
}
......@@ -4059,7 +4103,7 @@ void FullCodeGenerator::EnterFinallyBlock() {
void FullCodeGenerator::ExitFinallyBlock() {
DCHECK(!result_register().is(r4));
// Restore pending message from stack.
__ pop(r4);
PopOperand(r4);
ExternalReference pending_message_obj =
ExternalReference::address_of_pending_message_obj(isolate());
__ mov(ip, Operand(pending_message_obj));
......
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