summaryrefslogtreecommitdiff
path: root/deps/v8/src/full-codegen/ia32/full-codegen-ia32.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/full-codegen/ia32/full-codegen-ia32.cc')
-rw-r--r--deps/v8/src/full-codegen/ia32/full-codegen-ia32.cc400
1 files changed, 29 insertions, 371 deletions
diff --git a/deps/v8/src/full-codegen/ia32/full-codegen-ia32.cc b/deps/v8/src/full-codegen/ia32/full-codegen-ia32.cc
index 0af067c81d..5d9d1c5606 100644
--- a/deps/v8/src/full-codegen/ia32/full-codegen-ia32.cc
+++ b/deps/v8/src/full-codegen/ia32/full-codegen-ia32.cc
@@ -180,8 +180,6 @@ void FullCodeGenerator::Generate() {
__ push(edi);
__ Push(info->scope()->scope_info());
__ CallRuntime(Runtime::kNewScriptContext);
- PrepareForBailoutForId(BailoutId::ScriptContext(),
- BailoutState::TOS_REGISTER);
// The new target value is not used, clobbering is safe.
DCHECK_NULL(info->scope()->new_target_var());
} else {
@@ -242,12 +240,6 @@ void FullCodeGenerator::Generate() {
}
}
- // Register holding this function and new target are both trashed in case we
- // bailout here. But since that can happen only when new target is not used
- // and we allocate a context, the value of |function_in_register| is correct.
- PrepareForBailoutForId(BailoutId::FunctionContext(),
- BailoutState::NO_REGISTERS);
-
// We don't support new.target and rest parameters here.
DCHECK_NULL(info->scope()->new_target_var());
DCHECK_NULL(info->scope()->rest_parameter());
@@ -282,8 +274,6 @@ void FullCodeGenerator::Generate() {
}
// Visit the declarations and body.
- PrepareForBailoutForId(BailoutId::FunctionEntry(),
- BailoutState::NO_REGISTERS);
{
Comment cmnt(masm_, "[ Declarations");
VisitDeclarations(info->scope()->declarations());
@@ -296,8 +286,6 @@ void FullCodeGenerator::Generate() {
{
Comment cmnt(masm_, "[ Stack check");
- PrepareForBailoutForId(BailoutId::Declarations(),
- BailoutState::NO_REGISTERS);
Label ok;
ExternalReference stack_limit =
ExternalReference::address_of_stack_limit(isolate());
@@ -364,11 +352,6 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
EmitProfilingCounterReset();
__ bind(&ok);
- PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS);
- // Record a mapping of the OSR id to this PC. This is used if the OSR
- // entry becomes the target of a bailout. We don't expect it to be, but
- // we want it to work if it is.
- PrepareForBailoutForId(stmt->OsrEntryId(), BailoutState::NO_REGISTERS);
}
void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence(
@@ -459,9 +442,9 @@ void FullCodeGenerator::EffectContext::Plug(Handle<Object> lit) const {
void FullCodeGenerator::AccumulatorValueContext::Plug(
Handle<Object> lit) const {
if (lit->IsSmi()) {
- __ SafeMove(result_register(), Immediate(lit));
+ __ SafeMove(result_register(), Immediate(Smi::cast(*lit)));
} else {
- __ Move(result_register(), Immediate(lit));
+ __ Move(result_register(), Immediate(Handle<HeapObject>::cast(lit)));
}
}
@@ -469,18 +452,14 @@ void FullCodeGenerator::AccumulatorValueContext::Plug(
void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
codegen()->OperandStackDepthIncrement(1);
if (lit->IsSmi()) {
- __ SafePush(Immediate(lit));
+ __ SafePush(Immediate(Smi::cast(*lit)));
} else {
- __ push(Immediate(lit));
+ __ push(Immediate(Handle<HeapObject>::cast(lit)));
}
}
void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
- codegen()->PrepareForBailoutBeforeSplit(condition(),
- true,
- true_label_,
- false_label_);
DCHECK(lit->IsNullOrUndefined(isolate()) || !lit->IsUndetectable());
if (lit->IsNullOrUndefined(isolate()) || lit->IsFalse(isolate())) {
if (false_label_ != fall_through_) __ jmp(false_label_);
@@ -493,14 +472,14 @@ void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
if (true_label_ != fall_through_) __ jmp(true_label_);
}
} else if (lit->IsSmi()) {
- if (Smi::cast(*lit)->value() == 0) {
+ if (Smi::ToInt(*lit) == 0) {
if (false_label_ != fall_through_) __ jmp(false_label_);
} else {
if (true_label_ != fall_through_) __ jmp(true_label_);
}
} else {
// For simplicity we always test the accumulator register.
- __ mov(result_register(), lit);
+ __ mov(result_register(), Handle<HeapObject>::cast(lit));
codegen()->DoTest(this);
}
}
@@ -556,27 +535,21 @@ void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
- Handle<Object> value = flag
- ? isolate()->factory()->true_value()
- : isolate()->factory()->false_value();
+ Handle<HeapObject> value = flag ? isolate()->factory()->true_value()
+ : isolate()->factory()->false_value();
__ mov(result_register(), value);
}
void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
codegen()->OperandStackDepthIncrement(1);
- Handle<Object> value = flag
- ? isolate()->factory()->true_value()
- : isolate()->factory()->false_value();
+ Handle<HeapObject> value = flag ? isolate()->factory()->true_value()
+ : isolate()->factory()->false_value();
__ push(Immediate(value));
}
void FullCodeGenerator::TestContext::Plug(bool flag) const {
- codegen()->PrepareForBailoutBeforeSplit(condition(),
- true,
- true_label_,
- false_label_);
if (flag) {
if (true_label_ != fall_through_) __ jmp(true_label_);
} else {
@@ -589,8 +562,9 @@ void FullCodeGenerator::DoTest(Expression* condition,
Label* if_true,
Label* if_false,
Label* fall_through) {
- Handle<Code> ic = ToBooleanICStub::GetUninitialized(isolate());
- CallIC(ic, condition->test_id());
+ Callable callable = Builtins::CallableFor(isolate(), Builtins::kToBoolean);
+ __ Call(callable.code(), RelocInfo::CODE_TARGET);
+ RestoreContext();
__ CompareRoot(result_register(), Heap::kTrueValueRootIndex);
Split(equal, if_true, if_false, fall_through);
}
@@ -664,26 +638,6 @@ void FullCodeGenerator::SetVar(Variable* var,
}
-void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr,
- bool should_normalize,
- Label* if_true,
- Label* if_false) {
- // Only prepare for bailouts before splits if we're in a test
- // context. Otherwise, we let the Visit function deal with the
- // preparation to avoid preparing with the same AST id twice.
- if (!context()->IsTest()) return;
-
- Label skip;
- if (should_normalize) __ jmp(&skip, Label::kNear);
- PrepareForBailout(expr, BailoutState::TOS_REGISTER);
- if (should_normalize) {
- __ cmp(eax, isolate()->factory()->true_value());
- Split(equal, if_true, if_false, NULL);
- __ bind(&skip);
- }
-}
-
-
void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
// The variable in the declaration always resides in the current context.
DCHECK_EQ(0, scope()->ContextChainLength(variable->scope()));
@@ -729,7 +683,6 @@ void FullCodeGenerator::VisitVariableDeclaration(
__ mov(ContextOperand(esi, variable->index()),
Immediate(isolate()->factory()->the_hole_value()));
// No write barrier since the hole value is in old space.
- PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
}
break;
@@ -785,7 +738,6 @@ void FullCodeGenerator::VisitFunctionDeclaration(
kDontSaveFPRegs,
EMIT_REMEMBERED_SET,
OMIT_SMI_CHECK);
- PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
break;
}
@@ -814,7 +766,6 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
// Keep the switch value on the stack until a case matches.
VisitForStackValue(stmt->tag());
- PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS);
ZoneList<CaseClause*>* clauses = stmt->cases();
CaseClause* default_clause = NULL; // Can occur anywhere in the list.
@@ -858,12 +809,11 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
SetExpressionPosition(clause);
Handle<Code> ic =
CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code();
- CallIC(ic, clause->CompareId());
+ CallIC(ic);
patch_site.EmitPatchInfo();
Label skip;
__ jmp(&skip, Label::kNear);
- PrepareForBailout(clause, BailoutState::TOS_REGISTER);
__ cmp(eax, isolate()->factory()->true_value());
__ j(not_equal, &next_test);
__ Drop(1);
@@ -891,12 +841,10 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
Comment cmnt(masm_, "[ Case body");
CaseClause* clause = clauses->at(i);
__ bind(clause->body_target());
- PrepareForBailoutForId(clause->EntryId(), BailoutState::NO_REGISTERS);
VisitStatements(clause->statements());
}
__ bind(nested_statement.break_label());
- PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
}
@@ -929,7 +877,6 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ Call(isolate()->builtins()->ToObject(), RelocInfo::CODE_TARGET);
RestoreContext();
__ bind(&done_convert);
- PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER);
__ push(eax);
// Check cache validity in generated code. If we cannot guarantee cache
@@ -946,7 +893,6 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ bind(&call_runtime);
__ push(eax);
__ CallRuntime(Runtime::kForInEnumerate);
- PrepareForBailoutForId(stmt->EnumId(), BailoutState::TOS_REGISTER);
__ cmp(FieldOperand(eax, HeapObject::kMapOffset),
isolate()->factory()->meta_map());
__ j(not_equal, &fixed_array);
@@ -982,7 +928,6 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ push(eax); // Array
__ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset));
__ push(eax); // Fixed array length (as smi).
- PrepareForBailoutForId(stmt->PrepareId(), BailoutState::NO_REGISTERS);
__ push(Immediate(Smi::kZero)); // Initial index.
// Generate code for doing the condition check.
@@ -1019,7 +964,6 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// have the key or returns the name-converted key.
__ Call(isolate()->builtins()->ForInFilter(), RelocInfo::CODE_TARGET);
RestoreContext();
- PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER);
__ JumpIfRoot(result_register(), Heap::kUndefinedValueRootIndex,
loop_statement.continue_label());
@@ -1029,18 +973,14 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Perform the assignment as if via '='.
{ EffectContext context(this);
EmitAssignment(stmt->each(), stmt->EachFeedbackSlot());
- PrepareForBailoutForId(stmt->AssignmentId(), BailoutState::NO_REGISTERS);
}
- // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body().
- PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS);
// Generate code for the body of the loop.
Visit(stmt->body());
// Generate code for going to the next element by incrementing the
// index (smi) stored on top of the stack.
__ bind(loop_statement.continue_label());
- PrepareForBailoutForId(stmt->IncrementId(), BailoutState::NO_REGISTERS);
__ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1)));
EmitBackEdgeBookkeeping(stmt, &loop);
@@ -1051,7 +991,6 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
DropOperands(5);
// Exit and decrement the loop depth.
- PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
__ bind(&exit);
decrement_loop_depth();
}
@@ -1076,7 +1015,6 @@ void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer,
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
TypeofMode typeof_mode) {
SetExpressionPosition(proxy);
- PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
Variable* var = proxy->var();
// Two cases: global variables and all other types of variables.
@@ -1154,11 +1092,11 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
__ mov(ebx, Immediate(SmiFromSlot(expr->literal_slot())));
__ mov(ecx, Immediate(constant_properties));
__ mov(edx, Immediate(Smi::FromInt(flags)));
- Callable callable = CodeFactory::FastCloneShallowObject(isolate());
+ Callable callable =
+ Builtins::CallableFor(isolate(), Builtins::kFastCloneShallowObject);
__ Call(callable.code(), RelocInfo::CODE_TARGET);
RestoreContext();
}
- PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER);
// If result_saved is true the result is on top of the stack. If
// result_saved is false the result is in eax.
@@ -1193,7 +1131,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
DCHECK(StoreDescriptor::ValueRegister().is(eax));
__ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
CallStoreIC(property->GetSlot(0), key->value(), kStoreOwn);
- PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS);
if (NeedsHomeObject(value)) {
EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
}
@@ -1220,20 +1157,16 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
- PrepareForBailoutForId(expr->GetIdForPropertySet(i),
- BailoutState::NO_REGISTERS);
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
AccessorTable::Iterator it = accessor_table.lookup(key);
- it->second->bailout_id = expr->GetIdForPropertySet(i);
it->second->getter = property;
}
break;
case ObjectLiteral::Property::SETTER:
if (property->emit_store()) {
AccessorTable::Iterator it = accessor_table.lookup(key);
- it->second->bailout_id = expr->GetIdForPropertySet(i);
it->second->setter = property;
}
break;
@@ -1253,7 +1186,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
PushOperand(Smi::FromInt(NONE));
CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
- PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS);
}
if (result_saved) {
@@ -1285,7 +1217,6 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
__ Call(callable.code(), RelocInfo::CODE_TARGET);
RestoreContext();
}
- PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER);
bool result_saved = false; // Is the result saved to the stack?
ZoneList<Expression*>* subexprs = expr->values();
@@ -1311,8 +1242,6 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
Immediate(Smi::FromInt(array_index)));
__ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
CallKeyedStoreIC(expr->LiteralFeedbackSlot());
- PrepareForBailoutForId(expr->GetIdForElement(array_index),
- BailoutState::NO_REGISTERS);
}
if (result_saved) {
@@ -1371,17 +1300,12 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
switch (assign_type) {
case VARIABLE:
EmitVariableLoad(expr->target()->AsVariableProxy());
- PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER);
break;
case NAMED_PROPERTY:
EmitNamedPropertyLoad(property);
- PrepareForBailoutForId(property->LoadId(),
- BailoutState::TOS_REGISTER);
break;
case KEYED_PROPERTY:
EmitKeyedPropertyLoad(property);
- PrepareForBailoutForId(property->LoadId(),
- BailoutState::TOS_REGISTER);
break;
case NAMED_SUPER_PROPERTY:
case KEYED_SUPER_PROPERTY:
@@ -1394,17 +1318,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
PushOperand(eax); // Left operand goes on the stack.
VisitForAccumulatorValue(expr->value());
- if (ShouldInlineSmiCase(op)) {
- EmitInlineSmiBinaryOp(expr->binary_operation(),
- op,
- expr->target(),
- expr->value());
- } else {
- EmitBinaryOp(expr->binary_operation(), op);
- }
-
- // Deoptimization point in case the binary operation may have side effects.
- PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER);
+ EmitBinaryOp(expr->binary_operation(), op);
} else {
VisitForAccumulatorValue(expr->value());
}
@@ -1417,7 +1331,6 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
VariableProxy* proxy = expr->target()->AsVariableProxy();
EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(),
proxy->hole_check_mode());
- PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
context()->Plug(eax);
break;
}
@@ -1434,11 +1347,6 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
}
}
-void FullCodeGenerator::VisitSuspend(Suspend* expr) {
- // Resumable functions are not supported.
- UNREACHABLE();
-}
-
void FullCodeGenerator::PushOperand(MemOperand operand) {
OperandStackDepthIncrement(1);
__ Push(operand);
@@ -1455,132 +1363,11 @@ void FullCodeGenerator::EmitOperandStackDepthCheck() {
}
}
-void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
- Label allocate, done_allocate;
-
- __ Allocate(JSIteratorResult::kSize, eax, ecx, edx, &allocate,
- NO_ALLOCATION_FLAGS);
- __ jmp(&done_allocate, Label::kNear);
-
- __ bind(&allocate);
- __ Push(Smi::FromInt(JSIteratorResult::kSize));
- __ CallRuntime(Runtime::kAllocateInNewSpace);
-
- __ bind(&done_allocate);
- __ mov(ebx, NativeContextOperand());
- __ mov(ebx, ContextOperand(ebx, Context::ITERATOR_RESULT_MAP_INDEX));
- __ mov(FieldOperand(eax, HeapObject::kMapOffset), ebx);
- __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
- isolate()->factory()->empty_fixed_array());
- __ mov(FieldOperand(eax, JSObject::kElementsOffset),
- isolate()->factory()->empty_fixed_array());
- __ pop(FieldOperand(eax, JSIteratorResult::kValueOffset));
- __ mov(FieldOperand(eax, JSIteratorResult::kDoneOffset),
- isolate()->factory()->ToBoolean(done));
- STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
- OperandStackDepthDecrement(1);
-}
-
-
-void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
- Token::Value op,
- Expression* left,
- Expression* right) {
- // Do combined smi check of the operands. Left operand is on the
- // stack. Right operand is in eax.
- Label smi_case, done, stub_call;
- PopOperand(edx);
- __ mov(ecx, eax);
- __ or_(eax, edx);
- JumpPatchSite patch_site(masm_);
- patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear);
-
- __ bind(&stub_call);
- __ mov(eax, ecx);
- Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
- CallIC(code, expr->BinaryOperationFeedbackId());
- patch_site.EmitPatchInfo();
- __ jmp(&done, Label::kNear);
-
- // Smi case.
- __ bind(&smi_case);
- __ mov(eax, edx); // Copy left operand in case of a stub call.
-
- switch (op) {
- case Token::SAR:
- __ SmiUntag(ecx);
- __ sar_cl(eax); // No checks of result necessary
- __ and_(eax, Immediate(~kSmiTagMask));
- break;
- case Token::SHL: {
- Label result_ok;
- __ SmiUntag(eax);
- __ SmiUntag(ecx);
- __ shl_cl(eax);
- // Check that the *signed* result fits in a smi.
- __ cmp(eax, 0xc0000000);
- __ j(positive, &result_ok);
- __ SmiTag(ecx);
- __ jmp(&stub_call);
- __ bind(&result_ok);
- __ SmiTag(eax);
- break;
- }
- case Token::SHR: {
- Label result_ok;
- __ SmiUntag(eax);
- __ SmiUntag(ecx);
- __ shr_cl(eax);
- __ test(eax, Immediate(0xc0000000));
- __ j(zero, &result_ok);
- __ SmiTag(ecx);
- __ jmp(&stub_call);
- __ bind(&result_ok);
- __ SmiTag(eax);
- break;
- }
- case Token::ADD:
- __ add(eax, ecx);
- __ j(overflow, &stub_call);
- break;
- case Token::SUB:
- __ sub(eax, ecx);
- __ j(overflow, &stub_call);
- break;
- case Token::MUL: {
- __ SmiUntag(eax);
- __ imul(eax, ecx);
- __ j(overflow, &stub_call);
- __ test(eax, eax);
- __ j(not_zero, &done, Label::kNear);
- __ mov(ebx, edx);
- __ or_(ebx, ecx);
- __ j(negative, &stub_call);
- break;
- }
- case Token::BIT_OR:
- __ or_(eax, ecx);
- break;
- case Token::BIT_AND:
- __ and_(eax, ecx);
- break;
- case Token::BIT_XOR:
- __ xor_(eax, ecx);
- break;
- default:
- UNREACHABLE();
- }
-
- __ bind(&done);
- context()->Plug(eax);
-}
-
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
PopOperand(edx);
- Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
- JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
- CallIC(code, expr->BinaryOperationFeedbackId());
- patch_site.EmitPatchInfo();
+ Handle<Code> code = CodeFactory::BinaryOperation(isolate(), op).code();
+ __ Call(code, RelocInfo::CODE_TARGET);
+ RestoreContext();
context()->Plug(eax);
}
@@ -1700,7 +1487,6 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
PopOperand(StoreDescriptor::ReceiverRegister());
CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value());
- PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
context()->Plug(eax);
}
@@ -1715,7 +1501,6 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
PopOperand(StoreDescriptor::ReceiverRegister());
DCHECK(StoreDescriptor::ValueRegister().is(eax));
CallKeyedStoreIC(expr->AssignmentSlot());
- PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
context()->Plug(eax);
}
@@ -1728,7 +1513,6 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
if (callee->IsVariableProxy()) {
{ StackValueContext context(this);
EmitVariableLoad(callee->AsVariableProxy());
- PrepareForBailout(callee, BailoutState::NO_REGISTERS);
}
// Push undefined as receiver. This is patched in the method prologue if it
// is a sloppy mode method.
@@ -1740,8 +1524,6 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
DCHECK(!callee->AsProperty()->IsSuperAccess());
__ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
EmitNamedPropertyLoad(callee->AsProperty());
- PrepareForBailoutForId(callee->AsProperty()->LoadId(),
- BailoutState::TOS_REGISTER);
// Push the target function under the receiver.
PushOperand(Operand(esp, 0));
__ mov(Operand(esp, kPointerSize), eax);
@@ -1765,8 +1547,6 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
__ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
__ mov(LoadDescriptor::NameRegister(), eax);
EmitKeyedPropertyLoad(callee->AsProperty());
- PrepareForBailoutForId(callee->AsProperty()->LoadId(),
- BailoutState::TOS_REGISTER);
// Push the target function under the receiver.
PushOperand(Operand(esp, 0));
@@ -1784,26 +1564,14 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
VisitForStackValue(args->at(i));
}
- PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
- SetCallPosition(expr, expr->tail_call_mode());
- if (expr->tail_call_mode() == TailCallMode::kAllow) {
- if (FLAG_trace) {
- __ CallRuntime(Runtime::kTraceTailCall);
- }
- // Update profiling counters before the tail call since we will
- // not return to this function.
- EmitProfilingCounterHandlingForReturnSequence(true);
- }
- Handle<Code> code =
- CodeFactory::CallICTrampoline(isolate(), mode, expr->tail_call_mode())
- .code();
+ SetCallPosition(expr);
+ Handle<Code> code = CodeFactory::CallICTrampoline(isolate(), mode).code();
__ Move(edx, Immediate(IntFromSlot(expr->CallFeedbackICSlot())));
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
__ Move(eax, Immediate(arg_count));
CallIC(code);
OperandStackDepthDecrement(arg_count + 1);
- RecordJSReturnSite(expr);
RestoreContext();
context()->DropAndPlug(1, eax);
}
@@ -1842,7 +1610,6 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
CallConstructStub stub(isolate());
CallIC(stub.GetCode());
OperandStackDepthDecrement(arg_count + 1);
- PrepareForBailoutForId(expr->ReturnId(), BailoutState::TOS_REGISTER);
RestoreContext();
context()->Plug(eax);
}
@@ -1861,7 +1628,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
context()->PrepareTest(&materialize_true, &materialize_false,
&if_true, &if_false, &fall_through);
- PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
__ test(eax, Immediate(kSmiTagMask));
Split(zero, if_true, if_false, fall_through);
@@ -1884,7 +1650,6 @@ void FullCodeGenerator::EmitIsJSReceiver(CallRuntime* expr) {
__ JumpIfSmi(eax, if_false);
__ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ebx);
- PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(above_equal, if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
@@ -1906,7 +1671,6 @@ void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
__ JumpIfSmi(eax, if_false);
__ CmpObjectType(eax, JS_ARRAY_TYPE, ebx);
- PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(equal, if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
@@ -1928,7 +1692,6 @@ void FullCodeGenerator::EmitIsTypedArray(CallRuntime* expr) {
__ JumpIfSmi(eax, if_false);
__ CmpObjectType(eax, JS_TYPED_ARRAY_TYPE, ebx);
- PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(equal, if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
@@ -1950,7 +1713,6 @@ void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
__ JumpIfSmi(eax, if_false);
__ CmpObjectType(eax, JS_PROXY_TYPE, ebx);
- PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(equal, if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
@@ -2053,7 +1815,6 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) {
for (Expression* const arg : *args) {
VisitForStackValue(arg);
}
- PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
// Move target to edi.
int const argc = args->length() - 2;
__ mov(edi, Operand(esp, (argc + 1) * kPointerSize));
@@ -2086,36 +1847,6 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
}
-void FullCodeGenerator::EmitCreateIterResultObject(CallRuntime* expr) {
- ZoneList<Expression*>* args = expr->arguments();
- DCHECK_EQ(2, args->length());
- VisitForStackValue(args->at(0));
- VisitForStackValue(args->at(1));
-
- Label runtime, done;
-
- __ Allocate(JSIteratorResult::kSize, eax, ecx, edx, &runtime,
- NO_ALLOCATION_FLAGS);
- __ mov(ebx, NativeContextOperand());
- __ mov(ebx, ContextOperand(ebx, Context::ITERATOR_RESULT_MAP_INDEX));
- __ mov(FieldOperand(eax, HeapObject::kMapOffset), ebx);
- __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
- isolate()->factory()->empty_fixed_array());
- __ mov(FieldOperand(eax, JSObject::kElementsOffset),
- isolate()->factory()->empty_fixed_array());
- __ pop(FieldOperand(eax, JSIteratorResult::kDoneOffset));
- __ pop(FieldOperand(eax, JSIteratorResult::kValueOffset));
- STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
- __ jmp(&done, Label::kNear);
-
- __ bind(&runtime);
- CallRuntimeWithOperands(Runtime::kCreateIterResultObject);
-
- __ bind(&done);
- context()->Plug(eax);
-}
-
-
void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
// Push function.
__ LoadGlobalFunction(expr->context_index(), eax);
@@ -2217,8 +1948,6 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
&materialize_true);
if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
__ bind(&materialize_true);
- PrepareForBailoutForId(expr->MaterializeTrueId(),
- BailoutState::NO_REGISTERS);
if (context()->IsAccumulatorValue()) {
__ mov(eax, isolate()->factory()->true_value());
} else {
@@ -2226,8 +1955,6 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
}
__ jmp(&done, Label::kNear);
__ bind(&materialize_false);
- PrepareForBailoutForId(expr->MaterializeFalseId(),
- BailoutState::NO_REGISTERS);
if (context()->IsAccumulatorValue()) {
__ mov(eax, isolate()->factory()->false_value());
} else {
@@ -2300,65 +2027,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
}
- // We need a second deoptimization point after loading the value
- // in case evaluating the property load my have a side effect.
- if (assign_type == VARIABLE) {
- PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER);
- } else {
- PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
- }
-
- // Inline smi case if we are in a loop.
- Label done, stub_call;
- JumpPatchSite patch_site(masm_);
- if (ShouldInlineSmiCase(expr->op())) {
- Label slow;
- patch_site.EmitJumpIfNotSmi(eax, &slow, Label::kNear);
-
- // Save result for postfix expressions.
- if (expr->is_postfix()) {
- if (!context()->IsEffect()) {
- // Save the result on the stack. If we have a named or keyed property
- // we store the result under the receiver that is currently on top
- // of the stack.
- switch (assign_type) {
- case VARIABLE:
- __ push(eax);
- break;
- case NAMED_PROPERTY:
- __ mov(Operand(esp, kPointerSize), eax);
- break;
- case KEYED_PROPERTY:
- __ mov(Operand(esp, 2 * kPointerSize), eax);
- break;
- case NAMED_SUPER_PROPERTY:
- case KEYED_SUPER_PROPERTY:
- UNREACHABLE();
- break;
- }
- }
- }
-
- if (expr->op() == Token::INC) {
- __ add(eax, Immediate(Smi::FromInt(1)));
- } else {
- __ sub(eax, Immediate(Smi::FromInt(1)));
- }
- __ j(no_overflow, &done, Label::kNear);
- // Call stub. Undo operation first.
- if (expr->op() == Token::INC) {
- __ sub(eax, Immediate(Smi::FromInt(1)));
- } else {
- __ add(eax, Immediate(Smi::FromInt(1)));
- }
- __ jmp(&stub_call, Label::kNear);
- __ bind(&slow);
- }
-
// Convert old value into a number.
__ Call(isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
RestoreContext();
- PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
// Save result for postfix expressions.
if (expr->is_postfix()) {
@@ -2387,14 +2058,12 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
SetExpressionPosition(expr);
// Call stub for +1/-1.
- __ bind(&stub_call);
__ mov(edx, eax);
__ mov(eax, Immediate(Smi::FromInt(1)));
Handle<Code> code =
- CodeFactory::BinaryOpIC(isolate(), expr->binary_op()).code();
- CallIC(code, expr->CountBinOpFeedbackId());
- patch_site.EmitPatchInfo();
- __ bind(&done);
+ CodeFactory::BinaryOperation(isolate(), expr->binary_op()).code();
+ __ Call(code, RelocInfo::CODE_TARGET);
+ RestoreContext();
// Store the value returned in eax.
switch (assign_type) {
@@ -2405,8 +2074,6 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
{ EffectContext context(this);
EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(),
proxy->hole_check_mode());
- PrepareForBailoutForId(expr->AssignmentId(),
- BailoutState::TOS_REGISTER);
context.Plug(eax);
}
// For all contexts except EffectContext We have the result on
@@ -2418,8 +2085,6 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
// Perform the assignment as if via '='.
EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(),
proxy->hole_check_mode());
- PrepareForBailoutForId(expr->AssignmentId(),
- BailoutState::TOS_REGISTER);
context()->Plug(eax);
}
break;
@@ -2427,7 +2092,6 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
case NAMED_PROPERTY: {
PopOperand(StoreDescriptor::ReceiverRegister());
CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value());
- PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
if (expr->is_postfix()) {
if (!context()->IsEffect()) {
context()->PlugTOS();
@@ -2441,7 +2105,6 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
PopOperand(StoreDescriptor::NameRegister());
PopOperand(StoreDescriptor::ReceiverRegister());
CallKeyedStoreIC(expr->CountSlot());
- PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
if (expr->is_postfix()) {
// Result is on the stack
if (!context()->IsEffect()) {
@@ -2473,7 +2136,6 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
{ AccumulatorValueContext context(this);
VisitForTypeofValue(sub_expr);
}
- PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Factory* factory = isolate()->factory();
if (String::Equals(check, factory->number_string())) {
@@ -2552,7 +2214,6 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
VisitForStackValue(expr->right());
SetExpressionPosition(expr);
EmitHasProperty();
- PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
__ cmp(eax, isolate()->factory()->true_value());
Split(equal, if_true, if_false, fall_through);
break;
@@ -2563,7 +2224,6 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
PopOperand(edx);
__ Call(isolate()->builtins()->InstanceOf(), RelocInfo::CODE_TARGET);
RestoreContext();
- PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
__ cmp(eax, isolate()->factory()->true_value());
Split(equal, if_true, if_false, fall_through);
break;
@@ -2588,10 +2248,9 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
}
Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code();
- CallIC(ic, expr->CompareOperationFeedbackId());
+ CallIC(ic);
patch_site.EmitPatchInfo();
- PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
__ test(eax, eax);
Split(cc, if_true, if_false, fall_through);
}
@@ -2614,11 +2273,10 @@ void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr,
&if_true, &if_false, &fall_through);
VisitForAccumulatorValue(sub_expr);
- PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
- Handle<Object> nil_value = nil == kNullValue
- ? isolate()->factory()->null_value()
- : isolate()->factory()->undefined_value();
+ Handle<HeapObject> nil_value = nil == kNullValue
+ ? isolate()->factory()->null_value()
+ : isolate()->factory()->undefined_value();
if (expr->op() == Token::EQ_STRICT) {
__ cmp(eax, nil_value);
Split(equal, if_true, if_false, fall_through);