Fix issue 541 and some refactoring of the top-level compiler.

* Refactor VisitProperty to use the platform-specific methods for emitting the IC calls.
* Refactor recording of source positions in the top-level compiler.
* Correct the recorded source positions for assignments and property loads.
* Fix bug on x64 where source positions were not recorded before a calling a call-IC.
* Correct some inconsistencies between IA-32 and X64 top-level code generator.

We now pass all regression tests with 
--always-fast-compiler.

Review URL: http://codereview.chromium.org/550043

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3612 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent d234b0e2
......@@ -817,23 +817,19 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
}
void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop,
Expression::Context context) {
void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
__ mov(r2, Operand(key->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
Apply(context, r0);
}
void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop,
Expression::Context context) {
void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
Apply(context, r0);
}
......@@ -970,6 +966,9 @@ void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
__ CallRuntime(Runtime::kToSlowProperties, 1);
}
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ pop(r0);
__ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
......@@ -1001,6 +1000,9 @@ void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
__ CallRuntime(Runtime::kToSlowProperties, 1);
}
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ pop(r0);
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
......@@ -1024,24 +1026,16 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
Comment cmnt(masm_, "[ Property");
Expression* key = expr->key();
// Record the source position for the property load.
SetSourcePosition(expr->position());
// Evaluate receiver.
Visit(expr->obj());
if (key->IsPropertyName()) {
// Do a named property load. The IC expects the property name in r2 and
// the receiver on the stack.
__ mov(r2, Operand(key->AsLiteral()->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
EmitNamedPropertyLoad(expr);
// Drop receiver left on the stack by IC.
DropAndApply(1, expr->context(), r0);
} else {
// Do a keyed property load.
Visit(expr->key());
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
EmitKeyedPropertyLoad(expr);
// Drop key and receiver left on the stack by IC.
DropAndApply(2, expr->context(), r0);
}
......@@ -1383,12 +1377,13 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
Visit(prop->obj());
ASSERT_EQ(Expression::kValue, prop->obj()->context());
if (assign_type == NAMED_PROPERTY) {
EmitNamedPropertyLoad(prop, Expression::kValue);
EmitNamedPropertyLoad(prop);
} else {
Visit(prop->key());
ASSERT_EQ(Expression::kValue, prop->key()->context());
EmitKeyedPropertyLoad(prop, Expression::kValue);
EmitKeyedPropertyLoad(prop);
}
__ push(r0);
}
// Convert to number.
......
......@@ -639,9 +639,6 @@ void FastCodeGenerator::VisitLiteral(Literal* expr) {
void FastCodeGenerator::VisitAssignment(Assignment* expr) {
Comment cmnt(masm_, "[ Assignment");
// Record source code position of the (possible) IC call.
SetSourcePosition(expr->position());
// Left-hand side can only be a property, a global or a (parameter or local)
// slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
......@@ -682,10 +679,12 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
Expression::kValue);
break;
case NAMED_PROPERTY:
EmitNamedPropertyLoad(prop, Expression::kValue);
EmitNamedPropertyLoad(prop);
__ push(result_register());
break;
case KEYED_PROPERTY:
EmitKeyedPropertyLoad(prop, Expression::kValue);
EmitKeyedPropertyLoad(prop);
__ push(result_register());
break;
}
}
......@@ -700,6 +699,9 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
EmitCompoundAssignmentOp(expr->binary_op(), Expression::kValue);
}
// Record source position before possible IC call.
SetSourcePosition(expr->position());
// Store the value.
switch (assign_type) {
case VARIABLE:
......
......@@ -271,11 +271,11 @@ class FastCodeGenerator: public AstVisitor {
// Load a value from a named property.
// The receiver is left on the stack by the IC.
void EmitNamedPropertyLoad(Property* expr, Expression::Context context);
void EmitNamedPropertyLoad(Property* expr);
// Load a value from a keyed property.
// The receiver and the key is left on the stack by the IC.
void EmitKeyedPropertyLoad(Property* expr, Expression::Context context);
void EmitKeyedPropertyLoad(Property* expr);
// Apply the compound assignment operator. Expects both operands on top
// of the stack.
......
......@@ -127,7 +127,6 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
Move(dot_arguments_slot, ecx, ebx, edx);
}
{ Comment cmnt(masm_, "[ Declarations");
VisitDeclarations(fun->scope()->declarations());
}
......@@ -805,23 +804,21 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
}
void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop,
Expression::Context context) {
void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
__ mov(ecx, Immediate(key->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
Apply(context, eax);
__ nop();
}
void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop,
Expression::Context context) {
void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
Apply(context, eax);
__ nop();
}
......@@ -848,6 +845,7 @@ void FastCodeGenerator::EmitVariableAssignment(Variable* var,
__ push(CodeGenerator::GlobalObject());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
__ nop();
// Overwrite the receiver on the stack with the result if needed.
DropAndApply(1, context, eax);
......@@ -944,6 +942,9 @@ void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
__ CallRuntime(Runtime::kToSlowProperties, 1);
}
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ pop(eax);
__ mov(ecx, prop->key()->AsLiteral()->handle());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
......@@ -973,6 +974,9 @@ void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
__ CallRuntime(Runtime::kToSlowProperties, 1);
}
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ pop(eax);
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
......@@ -998,31 +1002,17 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
Comment cmnt(masm_, "[ Property");
Expression* key = expr->key();
// Record the source position for the property load.
SetSourcePosition(expr->position());
// Evaluate the receiver.
Visit(expr->obj());
if (key->IsPropertyName()) {
// Do a named property load. The IC expects the property name in ecx
// and the receiver on the stack.
__ mov(ecx, Immediate(key->AsLiteral()->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_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 it is treated specially by the LoadIC code.
__ nop();
EmitNamedPropertyLoad(expr);
// Drop receiver left on the stack by IC.
DropAndApply(1, expr->context(), eax);
} else {
// Do a keyed property load.
Visit(expr->key());
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 it is treated specially by the LoadIC code.
__ nop();
// Drop key left on the stack by IC.
EmitKeyedPropertyLoad(expr);
// Drop key and receiver left on the stack by IC.
DropAndApply(2, expr->context(), eax);
}
}
......@@ -1352,12 +1342,13 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
Visit(prop->obj());
ASSERT_EQ(Expression::kValue, prop->obj()->context());
if (assign_type == NAMED_PROPERTY) {
EmitNamedPropertyLoad(prop, Expression::kValue);
EmitNamedPropertyLoad(prop);
} else {
Visit(prop->key());
ASSERT_EQ(Expression::kValue, prop->key()->context());
EmitKeyedPropertyLoad(prop, Expression::kValue);
EmitKeyedPropertyLoad(prop);
}
__ push(eax);
}
// Convert to number.
......
......@@ -132,6 +132,10 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
Move(dot_arguments_slot, rcx, rbx, rdx);
}
{ Comment cmnt(masm_, "[ Declarations");
VisitDeclarations(fun->scope()->declarations());
}
{ Comment cmnt(masm_, "[ Stack check");
Label ok;
__ CompareRoot(rsp, Heap::kStackLimitRootIndex);
......@@ -141,10 +145,6 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
__ bind(&ok);
}
{ Comment cmnt(masm_, "[ Declarations");
VisitDeclarations(fun->scope()->declarations());
}
if (FLAG_trace) {
__ CallRuntime(Runtime::kTraceEnter, 0);
}
......@@ -817,23 +817,21 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
}
void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop,
Expression::Context context) {
void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
__ Move(rcx, key->handle());
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
Apply(context, rax);
__ nop();
}
void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop,
Expression::Context context) {
void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
Apply(context, rax);
__ nop();
}
......@@ -956,6 +954,9 @@ void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
__ CallRuntime(Runtime::kToSlowProperties, 1);
}
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ pop(rax);
__ Move(rcx, prop->key()->AsLiteral()->handle());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
......@@ -985,6 +986,9 @@ void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
__ CallRuntime(Runtime::kToSlowProperties, 1);
}
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ pop(rax);
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
......@@ -1010,30 +1014,16 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
Comment cmnt(masm_, "[ Property");
Expression* key = expr->key();
// Record the source position for the property load.
SetSourcePosition(expr->position());
// Evaluate receiver.
Visit(expr->obj());
if (key->IsPropertyName()) {
// Do a named property load. The IC expects the property name in rcx
// and the receiver on the stack.
__ Move(rcx, key->AsLiteral()->handle());
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_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 it is treated specially by the LoadIC code.
__ nop();
EmitNamedPropertyLoad(expr);
// Drop receiver left on the stack by IC.
DropAndApply(1, expr->context(), rax);
} else {
// Do a keyed property load.
Visit(expr->key());
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();
EmitKeyedPropertyLoad(expr);
// Drop key and receiver left on the stack by IC.
DropAndApply(2, expr->context(), rax);
}
......@@ -1053,9 +1043,10 @@ void FastCodeGenerator::EmitCallWithIC(Call* expr,
// Record source position for debugger.
SetSourcePosition(expr->position());
// Call the IC initialization code.
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
NOT_IN_LOOP);
__ call(ic, mode);
in_loop);
__ Call(ic, mode);
// Restore context register.
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
// Discard the function left on TOS.
......@@ -1371,12 +1362,13 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
Visit(prop->obj());
ASSERT_EQ(Expression::kValue, prop->obj()->context());
if (assign_type == NAMED_PROPERTY) {
EmitNamedPropertyLoad(prop, Expression::kValue);
EmitNamedPropertyLoad(prop);
} else {
Visit(prop->key());
ASSERT_EQ(Expression::kValue, prop->key()->context());
EmitKeyedPropertyLoad(prop, Expression::kValue);
EmitKeyedPropertyLoad(prop);
}
__ push(rax);
}
// Convert to number.
......
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