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
This commit is contained in:
parent
2133ee3fee
commit
b2306a41d0
@ -620,7 +620,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
|
||||
__ pop(r2); // Receiver.
|
||||
|
||||
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).
|
||||
}
|
||||
}
|
||||
@ -956,7 +956,7 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
|
||||
slow));
|
||||
__ mov(r0, Operand(key_literal->handle()));
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
__ jmp(done);
|
||||
}
|
||||
}
|
||||
@ -1022,7 +1022,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
|
||||
? RelocInfo::CODE_TARGET
|
||||
: RelocInfo::CODE_TARGET_CONTEXT;
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
||||
__ Call(ic, mode);
|
||||
EmitCallIC(ic, mode);
|
||||
}
|
||||
|
||||
|
||||
@ -1041,7 +1041,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
|
||||
__ ldr(r0, CodeGenerator::GlobalObject());
|
||||
__ mov(r2, Operand(var->name()));
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
||||
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
|
||||
Apply(context, r0);
|
||||
|
||||
} else if (slot != NULL && slot->type() == Slot::LOOKUP) {
|
||||
@ -1100,7 +1100,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
|
||||
|
||||
// Call keyed load IC. It has arguments key and receiver in r0 and r1.
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
Apply(context, r0);
|
||||
}
|
||||
}
|
||||
@ -1189,7 +1189,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
__ mov(r2, Operand(key->handle()));
|
||||
__ ldr(r1, MemOperand(sp));
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
break;
|
||||
}
|
||||
// Fall through.
|
||||
@ -1409,7 +1409,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
|
||||
__ mov(r2, Operand(key->handle()));
|
||||
// Call load IC. It has arguments receiver and property name r0 and r2.
|
||||
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) {
|
||||
SetSourcePosition(prop->position());
|
||||
// Call keyed load IC. It has arguments key and receiver in r0 and r1.
|
||||
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) {
|
||||
__ pop(r0); // Restore value.
|
||||
__ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
break;
|
||||
}
|
||||
case KEYED_PROPERTY: {
|
||||
@ -1486,7 +1486,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
|
||||
__ pop(r2);
|
||||
__ pop(r0); // Restore value.
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1509,7 +1509,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
|
||||
__ mov(r2, Operand(var->name()));
|
||||
__ ldr(r1, CodeGenerator::GlobalObject());
|
||||
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) {
|
||||
// Perform the assignment for non-const variables and for initialization
|
||||
@ -1598,7 +1598,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
|
||||
}
|
||||
|
||||
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 (expr->ends_initialization_block()) {
|
||||
@ -1642,7 +1642,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
|
||||
}
|
||||
|
||||
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 (expr->ends_initialization_block()) {
|
||||
@ -1691,7 +1691,7 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
|
||||
// Call the IC initialization code.
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
|
||||
__ Call(ic, mode);
|
||||
EmitCallIC(ic, mode);
|
||||
// Restore context register.
|
||||
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
Apply(context_, r0);
|
||||
@ -1715,7 +1715,7 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count,
|
||||
in_loop);
|
||||
__ Call(ic, mode);
|
||||
EmitCallIC(ic, mode);
|
||||
// Restore context register.
|
||||
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
Apply(context_, r0);
|
||||
@ -1854,7 +1854,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
__ pop(r1); // We do not need to keep the receiver.
|
||||
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
__ ldr(r1, CodeGenerator::GlobalObject());
|
||||
__ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
|
||||
__ Push(r0, r1); // Function, receiver.
|
||||
@ -2769,7 +2769,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ mov(r2, Operand(expr->name()));
|
||||
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
|
||||
NOT_IN_LOOP);
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
// Restore context register.
|
||||
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
} else {
|
||||
@ -3065,7 +3065,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
__ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
|
||||
__ pop(r1);
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
if (expr->is_postfix()) {
|
||||
if (context_ != Expression::kEffect) {
|
||||
ApplyTOS(context_);
|
||||
@ -3079,7 +3079,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
__ pop(r1); // Key.
|
||||
__ pop(r2); // Receiver.
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
if (expr->is_postfix()) {
|
||||
if (context_ != Expression::kEffect) {
|
||||
ApplyTOS(context_);
|
||||
@ -3102,7 +3102,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) {
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
||||
// Use a regular load, not a contextual load, to avoid a reference
|
||||
// error.
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
if (where == kStack) __ push(r0);
|
||||
} else if (proxy != NULL &&
|
||||
proxy->var()->slot() != NULL &&
|
||||
@ -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) {
|
||||
|
@ -509,6 +509,9 @@ class FullCodeGenerator: public AstVisitor {
|
||||
static Register result_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
|
||||
// offsets defined in, e.g., StandardFrameConstants.
|
||||
void StoreToFrameField(int frame_offset, Register value);
|
||||
|
@ -631,10 +631,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
|
||||
__ pop(edx);
|
||||
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
// Absence of a test eax instruction following the call
|
||||
// indicates that none of the load was inlined.
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -992,8 +989,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
|
||||
RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
|
||||
? RelocInfo::CODE_TARGET
|
||||
: RelocInfo::CODE_TARGET_CONTEXT;
|
||||
__ call(ic, mode);
|
||||
__ nop(); // Signal no inlined code.
|
||||
EmitCallIC(ic, mode);
|
||||
}
|
||||
|
||||
|
||||
@ -1070,7 +1066,7 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
|
||||
slow));
|
||||
__ mov(eax, Immediate(key_literal->handle()));
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
__ jmp(done);
|
||||
}
|
||||
}
|
||||
@ -1094,12 +1090,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
|
||||
__ mov(eax, CodeGenerator::GlobalObject());
|
||||
__ mov(ecx, var->name());
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
|
||||
// By emitting a nop we make sure that we do not have a test eax
|
||||
// instruction after the call it is treated specially by the LoadIC code
|
||||
// Remember that the assembler may choose to do peephole optimization
|
||||
// (eg, push/pop elimination).
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
|
||||
Apply(context, eax);
|
||||
|
||||
} else if (slot != NULL && slot->type() == Slot::LOOKUP) {
|
||||
@ -1162,10 +1153,8 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
|
||||
|
||||
// Do a keyed property load.
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
// Notice: We must not have a "test eax, ..." instruction after the
|
||||
// call. It is treated specially by the LoadIC code.
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
|
||||
// Drop key and object left on the stack by IC.
|
||||
Apply(context, eax);
|
||||
}
|
||||
@ -1263,8 +1252,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
__ mov(ecx, Immediate(key->handle()));
|
||||
__ mov(edx, Operand(esp, 0));
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
break;
|
||||
}
|
||||
// Fall through.
|
||||
@ -1477,16 +1465,14 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
|
||||
Literal* key = prop->key()->AsLiteral();
|
||||
__ mov(ecx, Immediate(key->handle()));
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
|
||||
SetSourcePosition(prop->position());
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
|
||||
@ -1846,8 +1832,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
|
||||
__ pop(eax); // Restore value.
|
||||
__ mov(ecx, prop->key()->AsLiteral()->handle());
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop(); // Signal no inlined code.
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
break;
|
||||
}
|
||||
case KEYED_PROPERTY: {
|
||||
@ -1858,8 +1843,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
|
||||
__ pop(edx);
|
||||
__ pop(eax); // Restore value.
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop(); // Signal no inlined code.
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1882,8 +1866,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
|
||||
__ mov(ecx, var->name());
|
||||
__ mov(edx, CodeGenerator::GlobalObject());
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
|
||||
} else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) {
|
||||
// Perform the assignment for non-const variables and for initialization
|
||||
@ -1967,8 +1950,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
|
||||
__ pop(edx);
|
||||
}
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
|
||||
// If the assignment ends an initialization block, revert to fast case.
|
||||
if (expr->ends_initialization_block()) {
|
||||
@ -2006,10 +1988,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
|
||||
// Record source code position before IC call.
|
||||
SetSourcePosition(expr->position());
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
||||
__ call(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();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
|
||||
// If the assignment ends an initialization block, revert to fast case.
|
||||
if (expr->ends_initialization_block()) {
|
||||
@ -2056,7 +2035,7 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
|
||||
SetSourcePosition(expr->position());
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
|
||||
__ call(ic, mode);
|
||||
EmitCallIC(ic, mode);
|
||||
// Restore context register.
|
||||
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
||||
Apply(context_, eax);
|
||||
@ -2079,7 +2058,7 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(
|
||||
arg_count, in_loop);
|
||||
__ call(ic, mode);
|
||||
EmitCallIC(ic, mode);
|
||||
// Restore context register.
|
||||
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
||||
Apply(context_, eax);
|
||||
@ -2203,7 +2182,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
} else {
|
||||
// Call to a keyed property.
|
||||
// For a synthetic property use keyed load IC followed by function call,
|
||||
// for a regular property use keyed CallIC.
|
||||
// for a regular property use keyed EmitCallIC.
|
||||
VisitForValue(prop->obj(), kStack);
|
||||
if (prop->is_synthetic()) {
|
||||
VisitForValue(prop->key(), kAccumulator);
|
||||
@ -2212,11 +2191,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
__ pop(edx); // We do not need to keep the receiver.
|
||||
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
// By emitting a nop we make sure that we do not have a "test eax,..."
|
||||
// instruction after the call as it is treated specially
|
||||
// by the LoadIC code.
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
// Push result (function).
|
||||
__ push(eax);
|
||||
// Push Global receiver.
|
||||
@ -3144,7 +3119,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ Set(ecx, Immediate(expr->name()));
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
// Restore context register.
|
||||
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
||||
} else {
|
||||
@ -3450,10 +3425,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
__ mov(ecx, prop->key()->AsLiteral()->handle());
|
||||
__ pop(edx);
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||
__ call(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();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
if (expr->is_postfix()) {
|
||||
if (context_ != Expression::kEffect) {
|
||||
ApplyTOS(context_);
|
||||
@ -3467,10 +3439,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
__ pop(ecx);
|
||||
__ pop(edx);
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
||||
__ call(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();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
if (expr->is_postfix()) {
|
||||
// Result is on the stack
|
||||
if (context_ != Expression::kEffect) {
|
||||
@ -3494,8 +3463,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) {
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
||||
// Use a regular load, not a contextual load, to avoid a reference
|
||||
// error.
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop(); // Signal no inlined code.
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
if (where == kStack) __ push(eax);
|
||||
} else if (proxy != NULL &&
|
||||
proxy->var()->slot() != NULL &&
|
||||
@ -3747,10 +3715,36 @@ void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
|
||||
}
|
||||
|
||||
|
||||
Register FullCodeGenerator::result_register() { return eax; }
|
||||
Register FullCodeGenerator::result_register() {
|
||||
return eax;
|
||||
}
|
||||
|
||||
|
||||
Register FullCodeGenerator::context_register() { return esi; }
|
||||
Register FullCodeGenerator::context_register() {
|
||||
return esi;
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
|
||||
ASSERT(mode == RelocInfo::CODE_TARGET ||
|
||||
mode == RelocInfo::CODE_TARGET_CONTEXT);
|
||||
__ call(ic, mode);
|
||||
|
||||
// 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) {
|
||||
|
@ -625,10 +625,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
|
||||
__ pop(rdx);
|
||||
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
// Absence of a test rax instruction following the call
|
||||
// indicates that none of the load was inlined.
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -941,8 +938,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
|
||||
RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
|
||||
? RelocInfo::CODE_TARGET
|
||||
: RelocInfo::CODE_TARGET_CONTEXT;
|
||||
__ call(ic, mode);
|
||||
__ nop(); // Signal no inlined code.
|
||||
EmitCallIC(ic, mode);
|
||||
}
|
||||
|
||||
|
||||
@ -1019,7 +1015,7 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
|
||||
slow));
|
||||
__ Move(rax, key_literal->handle());
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
__ jmp(done);
|
||||
}
|
||||
}
|
||||
@ -1043,11 +1039,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
|
||||
__ Move(rcx, var->name());
|
||||
__ movq(rax, CodeGenerator::GlobalObject());
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
||||
__ Call(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();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
|
||||
Apply(context, rax);
|
||||
|
||||
} else if (slot != NULL && slot->type() == Slot::LOOKUP) {
|
||||
@ -1110,10 +1102,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
|
||||
|
||||
// Do a keyed property load.
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
||||
__ call(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();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
Apply(context, rax);
|
||||
}
|
||||
}
|
||||
@ -1212,8 +1201,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
__ Move(rcx, key->handle());
|
||||
__ movq(rdx, Operand(rsp, 0));
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
break;
|
||||
}
|
||||
// Fall through.
|
||||
@ -1425,16 +1413,14 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
|
||||
Literal* key = prop->key()->AsLiteral();
|
||||
__ Move(rcx, key->handle());
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
|
||||
SetSourcePosition(prop->position());
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
|
||||
@ -1553,8 +1539,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
|
||||
__ pop(rax); // Restore value.
|
||||
__ Move(rcx, prop->key()->AsLiteral()->handle());
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop(); // Signal no inlined code.
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
break;
|
||||
}
|
||||
case KEYED_PROPERTY: {
|
||||
@ -1565,8 +1550,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
|
||||
__ pop(rdx);
|
||||
__ pop(rax);
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop(); // Signal no inlined code.
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1589,8 +1573,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
|
||||
__ Move(rcx, var->name());
|
||||
__ movq(rdx, CodeGenerator::GlobalObject());
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
|
||||
} else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) {
|
||||
// Perform the assignment for non-const variables and for initialization
|
||||
@ -1674,8 +1657,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
|
||||
__ pop(rdx);
|
||||
}
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
|
||||
// If the assignment ends an initialization block, revert to fast case.
|
||||
if (expr->ends_initialization_block()) {
|
||||
@ -1713,10 +1695,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
|
||||
// Record source code position before IC call.
|
||||
SetSourcePosition(expr->position());
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
||||
__ Call(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();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
|
||||
// If the assignment ends an initialization block, revert to fast case.
|
||||
if (expr->ends_initialization_block()) {
|
||||
@ -1765,7 +1744,7 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
|
||||
in_loop);
|
||||
__ Call(ic, mode);
|
||||
EmitCallIC(ic, mode);
|
||||
// Restore context register.
|
||||
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
||||
Apply(context_, rax);
|
||||
@ -1789,7 +1768,7 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count,
|
||||
in_loop);
|
||||
__ Call(ic, mode);
|
||||
EmitCallIC(ic, mode);
|
||||
// Restore context register.
|
||||
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
||||
Apply(context_, rax);
|
||||
@ -1924,11 +1903,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
// Record source code position for IC call.
|
||||
SetSourcePosition(prop->position());
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
||||
__ call(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();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
// Pop receiver.
|
||||
__ pop(rbx);
|
||||
// Push result (function).
|
||||
@ -2841,7 +2816,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
||||
__ Move(rcx, expr->name());
|
||||
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
||||
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
|
||||
__ call(ic, RelocInfo::CODE_TARGET);
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
// Restore context register.
|
||||
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
||||
} else {
|
||||
@ -3139,10 +3114,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
__ Move(rcx, prop->key()->AsLiteral()->handle());
|
||||
__ pop(rdx);
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||
__ call(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();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
if (expr->is_postfix()) {
|
||||
if (context_ != Expression::kEffect) {
|
||||
ApplyTOS(context_);
|
||||
@ -3156,10 +3128,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
__ pop(rcx);
|
||||
__ pop(rdx);
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
||||
__ call(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();
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
if (expr->is_postfix()) {
|
||||
if (context_ != Expression::kEffect) {
|
||||
ApplyTOS(context_);
|
||||
@ -3182,8 +3151,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) {
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
||||
// Use a regular load, not a contextual load, to avoid a reference
|
||||
// error.
|
||||
__ Call(ic, RelocInfo::CODE_TARGET);
|
||||
__ nop(); // Signal no inlined code.
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
if (where == kStack) __ push(rax);
|
||||
} else if (proxy != NULL &&
|
||||
proxy->var()->slot() != NULL &&
|
||||
@ -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; }
|
||||
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);
|
||||
|
||||
// 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) {
|
||||
|
@ -1315,7 +1315,6 @@ void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) {
|
||||
|
||||
void MacroAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) {
|
||||
ASSERT(RelocInfo::IsCodeTarget(rmode));
|
||||
WriteRecordedPositions();
|
||||
call(code_object, rmode);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user