Commit b2306a41 authored by kasperl@chromium.org's avatar kasperl@chromium.org

Clean up the insertion of nops (signalling non-inlined loads and

stores) in the full codegens.
Review URL: http://codereview.chromium.org/3431010

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5470 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 2133ee3f
...@@ -620,7 +620,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable, ...@@ -620,7 +620,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
__ pop(r2); // Receiver. __ pop(r2); // Receiver.
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
// Value in r0 is ignored (declarations are statements). // Value in r0 is ignored (declarations are statements).
} }
} }
...@@ -956,7 +956,7 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase( ...@@ -956,7 +956,7 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
slow)); slow));
__ mov(r0, Operand(key_literal->handle())); __ mov(r0, Operand(key_literal->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ jmp(done); __ jmp(done);
} }
} }
...@@ -1022,7 +1022,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( ...@@ -1022,7 +1022,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
? RelocInfo::CODE_TARGET ? RelocInfo::CODE_TARGET
: RelocInfo::CODE_TARGET_CONTEXT; : RelocInfo::CODE_TARGET_CONTEXT;
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, mode); EmitCallIC(ic, mode);
} }
...@@ -1041,7 +1041,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var, ...@@ -1041,7 +1041,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
__ ldr(r0, CodeGenerator::GlobalObject()); __ ldr(r0, CodeGenerator::GlobalObject());
__ mov(r2, Operand(var->name())); __ mov(r2, Operand(var->name()));
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
Apply(context, r0); Apply(context, r0);
} else if (slot != NULL && slot->type() == Slot::LOOKUP) { } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
...@@ -1100,7 +1100,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var, ...@@ -1100,7 +1100,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
// Call keyed load IC. It has arguments key and receiver in r0 and r1. // Call keyed load IC. It has arguments key and receiver in r0 and r1.
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
Apply(context, r0); Apply(context, r0);
} }
} }
...@@ -1189,7 +1189,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -1189,7 +1189,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
__ mov(r2, Operand(key->handle())); __ mov(r2, Operand(key->handle()));
__ ldr(r1, MemOperand(sp)); __ ldr(r1, MemOperand(sp));
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
break; break;
} }
// Fall through. // Fall through.
...@@ -1409,7 +1409,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { ...@@ -1409,7 +1409,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
__ mov(r2, Operand(key->handle())); __ mov(r2, Operand(key->handle()));
// Call load IC. It has arguments receiver and property name r0 and r2. // Call load IC. It has arguments receiver and property name r0 and r2.
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
} }
...@@ -1417,7 +1417,7 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { ...@@ -1417,7 +1417,7 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position()); SetSourcePosition(prop->position());
// Call keyed load IC. It has arguments key and receiver in r0 and r1. // Call keyed load IC. It has arguments key and receiver in r0 and r1.
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
} }
...@@ -1475,7 +1475,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) { ...@@ -1475,7 +1475,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
__ pop(r0); // Restore value. __ pop(r0); // Restore value.
__ mov(r2, Operand(prop->key()->AsLiteral()->handle())); __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
break; break;
} }
case KEYED_PROPERTY: { case KEYED_PROPERTY: {
...@@ -1486,7 +1486,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) { ...@@ -1486,7 +1486,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
__ pop(r2); __ pop(r2);
__ pop(r0); // Restore value. __ pop(r0); // Restore value.
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
break; break;
} }
} }
...@@ -1509,7 +1509,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, ...@@ -1509,7 +1509,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
__ mov(r2, Operand(var->name())); __ mov(r2, Operand(var->name()));
__ ldr(r1, CodeGenerator::GlobalObject()); __ ldr(r1, CodeGenerator::GlobalObject());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
} else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) {
// Perform the assignment for non-const variables and for initialization // Perform the assignment for non-const variables and for initialization
...@@ -1598,7 +1598,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { ...@@ -1598,7 +1598,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
} }
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
// If the assignment ends an initialization block, revert to fast case. // If the assignment ends an initialization block, revert to fast case.
if (expr->ends_initialization_block()) { if (expr->ends_initialization_block()) {
...@@ -1642,7 +1642,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { ...@@ -1642,7 +1642,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
} }
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
// If the assignment ends an initialization block, revert to fast case. // If the assignment ends an initialization block, revert to fast case.
if (expr->ends_initialization_block()) { if (expr->ends_initialization_block()) {
...@@ -1691,7 +1691,7 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr, ...@@ -1691,7 +1691,7 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
// Call the IC initialization code. // Call the IC initialization code.
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
__ Call(ic, mode); EmitCallIC(ic, mode);
// Restore context register. // Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
Apply(context_, r0); Apply(context_, r0);
...@@ -1715,7 +1715,7 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, ...@@ -1715,7 +1715,7 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count, Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count,
in_loop); in_loop);
__ Call(ic, mode); EmitCallIC(ic, mode);
// Restore context register. // Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
Apply(context_, r0); Apply(context_, r0);
...@@ -1854,7 +1854,7 @@ void FullCodeGenerator::VisitCall(Call* expr) { ...@@ -1854,7 +1854,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ pop(r1); // We do not need to keep the receiver. __ pop(r1); // We do not need to keep the receiver.
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ ldr(r1, CodeGenerator::GlobalObject()); __ ldr(r1, CodeGenerator::GlobalObject());
__ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
__ Push(r0, r1); // Function, receiver. __ Push(r0, r1); // Function, receiver.
...@@ -2769,7 +2769,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { ...@@ -2769,7 +2769,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ mov(r2, Operand(expr->name())); __ mov(r2, Operand(expr->name()));
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
NOT_IN_LOOP); NOT_IN_LOOP);
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
// Restore context register. // Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
} else { } else {
...@@ -3065,7 +3065,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -3065,7 +3065,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ mov(r2, Operand(prop->key()->AsLiteral()->handle())); __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
__ pop(r1); __ pop(r1);
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
if (expr->is_postfix()) { if (expr->is_postfix()) {
if (context_ != Expression::kEffect) { if (context_ != Expression::kEffect) {
ApplyTOS(context_); ApplyTOS(context_);
...@@ -3079,7 +3079,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -3079,7 +3079,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ pop(r1); // Key. __ pop(r1); // Key.
__ pop(r2); // Receiver. __ pop(r2); // Receiver.
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
if (expr->is_postfix()) { if (expr->is_postfix()) {
if (context_ != Expression::kEffect) { if (context_ != Expression::kEffect) {
ApplyTOS(context_); ApplyTOS(context_);
...@@ -3102,7 +3102,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) { ...@@ -3102,7 +3102,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) {
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
// Use a regular load, not a contextual load, to avoid a reference // Use a regular load, not a contextual load, to avoid a reference
// error. // error.
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
if (where == kStack) __ push(r0); if (where == kStack) __ push(r0);
} else if (proxy != NULL && } else if (proxy != NULL &&
proxy->var()->slot() != NULL && proxy->var()->slot() != NULL &&
...@@ -3365,10 +3365,21 @@ void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { ...@@ -3365,10 +3365,21 @@ void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
} }
Register FullCodeGenerator::result_register() { return r0; } Register FullCodeGenerator::result_register() {
return r0;
}
Register FullCodeGenerator::context_register() { return cp; } Register FullCodeGenerator::context_register() {
return cp;
}
void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
ASSERT(mode == RelocInfo::CODE_TARGET ||
mode == RelocInfo::CODE_TARGET_CONTEXT);
__ Call(ic, mode);
}
void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
......
...@@ -509,6 +509,9 @@ class FullCodeGenerator: public AstVisitor { ...@@ -509,6 +509,9 @@ class FullCodeGenerator: public AstVisitor {
static Register result_register(); static Register result_register();
static Register context_register(); static Register context_register();
// Helper for calling an IC stub.
void EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode);
// Set fields in the stack frame. Offsets are the frame pointer relative // Set fields in the stack frame. Offsets are the frame pointer relative
// offsets defined in, e.g., StandardFrameConstants. // offsets defined in, e.g., StandardFrameConstants.
void StoreToFrameField(int frame_offset, Register value); void StoreToFrameField(int frame_offset, Register value);
......
This diff is collapsed.
...@@ -625,10 +625,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable, ...@@ -625,10 +625,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
__ pop(rdx); __ pop(rdx);
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
// Absence of a test rax instruction following the call
// indicates that none of the load was inlined.
__ nop();
} }
} }
} }
...@@ -941,8 +938,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( ...@@ -941,8 +938,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
? RelocInfo::CODE_TARGET ? RelocInfo::CODE_TARGET
: RelocInfo::CODE_TARGET_CONTEXT; : RelocInfo::CODE_TARGET_CONTEXT;
__ call(ic, mode); EmitCallIC(ic, mode);
__ nop(); // Signal no inlined code.
} }
...@@ -1019,7 +1015,7 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase( ...@@ -1019,7 +1015,7 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
slow)); slow));
__ Move(rax, key_literal->handle()); __ Move(rax, key_literal->handle());
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ jmp(done); __ jmp(done);
} }
} }
...@@ -1043,11 +1039,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var, ...@@ -1043,11 +1039,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
__ Move(rcx, var->name()); __ Move(rcx, var->name());
__ movq(rax, CodeGenerator::GlobalObject()); __ movq(rax, CodeGenerator::GlobalObject());
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
// A test rax instruction following the call is used by the IC to
// indicate that the inobject property case was inlined. Ensure there
// is no test rax instruction here.
__ nop();
Apply(context, rax); Apply(context, rax);
} else if (slot != NULL && slot->type() == Slot::LOOKUP) { } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
...@@ -1110,10 +1102,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var, ...@@ -1110,10 +1102,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
// Do a keyed property load. // Do a keyed property load.
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
// Notice: We must not have a "test rax, ..." instruction after the
// call. It is treated specially by the LoadIC code.
__ nop();
Apply(context, rax); Apply(context, rax);
} }
} }
...@@ -1212,8 +1201,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -1212,8 +1201,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
__ Move(rcx, key->handle()); __ Move(rcx, key->handle());
__ movq(rdx, Operand(rsp, 0)); __ movq(rdx, Operand(rsp, 0));
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ nop();
break; break;
} }
// Fall through. // Fall through.
...@@ -1425,16 +1413,14 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { ...@@ -1425,16 +1413,14 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
Literal* key = prop->key()->AsLiteral(); Literal* key = prop->key()->AsLiteral();
__ Move(rcx, key->handle()); __ Move(rcx, key->handle());
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ nop();
} }
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position()); SetSourcePosition(prop->position());
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ nop();
} }
...@@ -1553,8 +1539,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) { ...@@ -1553,8 +1539,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
__ pop(rax); // Restore value. __ pop(rax); // Restore value.
__ Move(rcx, prop->key()->AsLiteral()->handle()); __ Move(rcx, prop->key()->AsLiteral()->handle());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ nop(); // Signal no inlined code.
break; break;
} }
case KEYED_PROPERTY: { case KEYED_PROPERTY: {
...@@ -1565,8 +1550,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) { ...@@ -1565,8 +1550,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
__ pop(rdx); __ pop(rdx);
__ pop(rax); __ pop(rax);
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ nop(); // Signal no inlined code.
break; break;
} }
} }
...@@ -1589,8 +1573,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, ...@@ -1589,8 +1573,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
__ Move(rcx, var->name()); __ Move(rcx, var->name());
__ movq(rdx, CodeGenerator::GlobalObject()); __ movq(rdx, CodeGenerator::GlobalObject());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ nop();
} else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) {
// Perform the assignment for non-const variables and for initialization // Perform the assignment for non-const variables and for initialization
...@@ -1674,8 +1657,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { ...@@ -1674,8 +1657,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
__ pop(rdx); __ pop(rdx);
} }
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ nop();
// If the assignment ends an initialization block, revert to fast case. // If the assignment ends an initialization block, revert to fast case.
if (expr->ends_initialization_block()) { if (expr->ends_initialization_block()) {
...@@ -1713,10 +1695,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { ...@@ -1713,10 +1695,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// Record source code position before IC call. // Record source code position before IC call.
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
// This nop signals to the IC that there is no inlined code at the call
// site for it to patch.
__ nop();
// If the assignment ends an initialization block, revert to fast case. // If the assignment ends an initialization block, revert to fast case.
if (expr->ends_initialization_block()) { if (expr->ends_initialization_block()) {
...@@ -1765,7 +1744,7 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr, ...@@ -1765,7 +1744,7 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
in_loop); in_loop);
__ Call(ic, mode); EmitCallIC(ic, mode);
// Restore context register. // Restore context register.
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
Apply(context_, rax); Apply(context_, rax);
...@@ -1789,7 +1768,7 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, ...@@ -1789,7 +1768,7 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count, Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count,
in_loop); in_loop);
__ Call(ic, mode); EmitCallIC(ic, mode);
// Restore context register. // Restore context register.
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
Apply(context_, rax); Apply(context_, rax);
...@@ -1924,11 +1903,7 @@ void FullCodeGenerator::VisitCall(Call* expr) { ...@@ -1924,11 +1903,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// Record source code position for IC call. // Record source code position for IC call.
SetSourcePosition(prop->position()); SetSourcePosition(prop->position());
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
// By emitting a nop we make sure that we do not have a "test rax,..."
// instruction after the call as it is treated specially
// by the LoadIC code.
__ nop();
// Pop receiver. // Pop receiver.
__ pop(rbx); __ pop(rbx);
// Push result (function). // Push result (function).
...@@ -2841,7 +2816,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { ...@@ -2841,7 +2816,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ Move(rcx, expr->name()); __ Move(rcx, expr->name());
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
__ call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
// Restore context register. // Restore context register.
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
} else { } else {
...@@ -3139,10 +3114,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -3139,10 +3114,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ Move(rcx, prop->key()->AsLiteral()->handle()); __ Move(rcx, prop->key()->AsLiteral()->handle());
__ pop(rdx); __ pop(rdx);
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
// This nop signals to the IC that there is no inlined code at the call
// site for it to patch.
__ nop();
if (expr->is_postfix()) { if (expr->is_postfix()) {
if (context_ != Expression::kEffect) { if (context_ != Expression::kEffect) {
ApplyTOS(context_); ApplyTOS(context_);
...@@ -3156,10 +3128,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -3156,10 +3128,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ pop(rcx); __ pop(rcx);
__ pop(rdx); __ pop(rdx);
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
// This nop signals to the IC that there is no inlined code at the call
// site for it to patch.
__ nop();
if (expr->is_postfix()) { if (expr->is_postfix()) {
if (context_ != Expression::kEffect) { if (context_ != Expression::kEffect) {
ApplyTOS(context_); ApplyTOS(context_);
...@@ -3182,8 +3151,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) { ...@@ -3182,8 +3151,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) {
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
// Use a regular load, not a contextual load, to avoid a reference // Use a regular load, not a contextual load, to avoid a reference
// error. // error.
__ Call(ic, RelocInfo::CODE_TARGET); EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ nop(); // Signal no inlined code.
if (where == kStack) __ push(rax); if (where == kStack) __ push(rax);
} else if (proxy != NULL && } else if (proxy != NULL &&
proxy->var()->slot() != NULL && proxy->var()->slot() != NULL &&
...@@ -3431,10 +3399,36 @@ void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { ...@@ -3431,10 +3399,36 @@ void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
} }
Register FullCodeGenerator::result_register() { return rax; } Register FullCodeGenerator::result_register() {
return rax;
}
Register FullCodeGenerator::context_register() {
return rsi;
}
void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
ASSERT(mode == RelocInfo::CODE_TARGET ||
mode == RelocInfo::CODE_TARGET_CONTEXT);
__ call(ic, mode);
Register FullCodeGenerator::context_register() { return rsi; } // If we're calling a (keyed) load or store stub, we have to mark
// the call as containing no inlined code so we will not attempt to
// patch it.
switch (ic->kind()) {
case Code::LOAD_IC:
case Code::KEYED_LOAD_IC:
case Code::STORE_IC:
case Code::KEYED_STORE_IC:
__ nop(); // Signals no inlined code.
break;
default:
// Do nothing.
break;
}
}
void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
......
...@@ -1315,7 +1315,6 @@ void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) { ...@@ -1315,7 +1315,6 @@ void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) {
void MacroAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) { void MacroAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) {
ASSERT(RelocInfo::IsCodeTarget(rmode)); ASSERT(RelocInfo::IsCodeTarget(rmode));
WriteRecordedPositions();
call(code_object, rmode); call(code_object, rmode);
} }
......
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