Author: [email protected]
Date: Thu Jan 8 06:02:13 2009
New Revision: 1049
Modified:
branches/experimental/toiger/src/codegen-ia32.cc
branches/experimental/toiger/src/codegen-ia32.h
branches/experimental/toiger/src/virtual-frame-ia32.cc
Log:
Add register allocation for a lot of calls.
Review URL: http://codereview.chromium.org/17414
Modified: branches/experimental/toiger/src/codegen-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/codegen-ia32.cc (original)
+++ branches/experimental/toiger/src/codegen-ia32.cc Thu Jan 8 06:02:13
2009
@@ -477,13 +477,22 @@
void CodeGenerator::LoadGlobal() {
- frame_->EmitPush(GlobalObject());
+ if (in_spilled_code()) {
+ frame_->EmitPush(GlobalObject());
+ } else {
+ Result temp = allocator_->Allocate();
+ __ mov(temp.reg(), GlobalObject());
+ frame_->Push(&temp);
+ }
}
-void CodeGenerator::LoadGlobalReceiver(Register scratch) {
- __ mov(scratch, GlobalObject());
- frame_->EmitPush(FieldOperand(scratch,
GlobalObject::kGlobalReceiverOffset));
+void CodeGenerator::LoadGlobalReceiver() {
+ Result temp = allocator_->Allocate();
+ Register reg = temp.reg();
+ __ mov(reg, GlobalObject());
+ __ mov(reg, FieldOperand(reg, GlobalObject::kGlobalReceiverOffset));
+ frame_->Push(&temp);
}
@@ -1361,7 +1370,7 @@
// Push the arguments ("left-to-right") on the stack.
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
- LoadAndSpill(args->at(i));
+ Load(args->at(i));
}
// Record the position for debugging purposes.
@@ -1370,10 +1379,12 @@
// Use the shared code stub to call the function.
CallFunctionStub call_function(arg_count);
frame_->CallStub(&call_function, arg_count + 1);
+ Result result = allocator_->Allocate(eax);
- // Restore context and pop function from the stack.
+ // Restore context and replace function on the stack with the
+ // result of the stub invocation.
frame_->RestoreContextRegister();
- __ mov(frame_->Top(), eax);
+ frame_->SetElementAt(0, &result);
}
@@ -3172,7 +3183,6 @@
void CodeGenerator::VisitCall(Call* node) {
- VirtualFrame::SpilledScope spilled_scope(this);
Comment cmnt(masm_, "[ Call");
ZoneList<Expression*>* args = node->arguments();
@@ -3199,16 +3209,17 @@
// ----------------------------------
// Push the name of the function and the receiver onto the stack.
- frame_->EmitPush(Immediate(var->name()));
+ frame_->Push(var->name());
// Pass the global object as the receiver and let the IC stub
// patch the stack to use the global proxy as 'this' in the
// invoked function.
LoadGlobal();
+
// Load the arguments.
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
- LoadAndSpill(args->at(i));
+ Load(args->at(i));
}
// Setup the receiver register and call the IC initialization code.
@@ -3218,10 +3229,11 @@
CodeForSourcePosition(node->position());
frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT,
arg_count + 1);
+ Result result = allocator_->Allocate(eax);
frame_->RestoreContextRegister();
- // Overwrite the function on the stack with the result.
- __ mov(frame_->Top(), eax);
+ // Replace the function on the stack with the result.
+ frame_->SetElementAt(0, &result);
} else if (var != NULL && var->slot() != NULL &&
var->slot()->type() == Slot::LOOKUP) {
@@ -3230,14 +3242,14 @@
// ----------------------------------
// Load the function
- frame_->EmitPush(esi);
- frame_->EmitPush(Immediate(var->name()));
+ frame_->Push(esi);
+ frame_->Push(var->name());
frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
// eax: slot value; edx: receiver
// Load the receiver.
- frame_->EmitPush(eax);
- frame_->EmitPush(edx);
+ frame_->Push(eax);
+ frame_->Push(edx);
// Call the function.
CallWithArguments(args, node->position());
@@ -3252,13 +3264,13 @@
// ------------------------------------------------------------------
// Push the name of the function and the receiver onto the stack.
- frame_->EmitPush(Immediate(literal->handle()));
- LoadAndSpill(property->obj());
+ frame_->Push(literal->handle());
+ Load(property->obj());
// Load the arguments.
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
- LoadAndSpill(args->at(i));
+ Load(args->at(i));
}
// Call the IC initialization code.
@@ -3267,10 +3279,11 @@
: ComputeCallInitialize(arg_count);
CodeForSourcePosition(node->position());
frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1);
+ Result result = allocator_->Allocate(eax);
frame_->RestoreContextRegister();
- // Overwrite the function on the stack with the result.
- __ mov(frame_->Top(), eax);
+ // Replace the function on the stack with the result.
+ frame_->SetElementAt(0, &result);
} else {
// -------------------------------------------
@@ -3279,11 +3292,11 @@
// Load the function to call from the property through a reference.
Reference ref(this, property);
- frame_->SpillAll();
- ref.GetValueAndSpill(NOT_INSIDE_TYPEOF);
+ ref.GetValue(NOT_INSIDE_TYPEOF);
// Pass receiver to called function.
// The reference's size is non-negative.
+ frame_->SpillAll();
frame_->EmitPush(frame_->ElementAt(ref.size()));
// Call the function.
@@ -3296,10 +3309,10 @@
// ----------------------------------
// Load the function.
- LoadAndSpill(function);
+ Load(function);
// Pass the global proxy as the receiver.
- LoadGlobalReceiver(eax);
+ LoadGlobalReceiver();
// Call the function.
CallWithArguments(args, node->position());
@@ -3308,7 +3321,6 @@
void CodeGenerator::VisitCallNew(CallNew* node) {
- VirtualFrame::SpilledScope spilled_scope(this);
Comment cmnt(masm_, "[ CallNew");
CodeForStatement(node);
@@ -3321,16 +3333,20 @@
// Compute function to call and use the global object as the
// receiver. There is no need to use the global proxy here because
// it will always be replaced with a newly allocated object.
- LoadAndSpill(node->expression());
+ Load(node->expression());
LoadGlobal();
// Push the arguments ("left-to-right") on the stack.
ZoneList<Expression*>* args = node->arguments();
int arg_count = args->length();
for (int i = 0; i < arg_count; i++) {
- LoadAndSpill(args->at(i));
+ Load(args->at(i));
}
+ // TODO(): Get rid of this spilling. It is only necessary because we
+ // load the function from the non-virtual stack.
+ frame_->SpillAll();
+
// Constructors are called with the number of arguments in register
// eax for now. Another option would be to have separate construct
// call trampolines per different arguments counts encountered.
@@ -3345,8 +3361,10 @@
CodeForSourcePosition(node->position());
Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall));
frame_->CallCodeObject(ic, RelocInfo::CONSTRUCT_CALL, args->length() +
1);
- // Discard the function and "push" the newly created object.
- __ mov(frame_->Top(), eax);
+ Result result = allocator_->Allocate(eax);
+
+ // Replace the function on the stack with the result.
+ frame_->SetElementAt(0, &result);
}
@@ -3365,6 +3383,7 @@
// Prepare stack for call to resolved function.
LoadAndSpill(function);
+
// Allocate a frame slot for the receiver.
frame_->EmitPush(Immediate(Factory::undefined_value()));
int arg_count = args->length();
Modified: branches/experimental/toiger/src/codegen-ia32.h
==============================================================================
--- branches/experimental/toiger/src/codegen-ia32.h (original)
+++ branches/experimental/toiger/src/codegen-ia32.h Thu Jan 8 06:02:13 2009
@@ -296,7 +296,7 @@
bool force_cc);
void Load(Expression* x, TypeofState typeof_state = NOT_INSIDE_TYPEOF);
void LoadGlobal();
- void LoadGlobalReceiver(Register scratch);
+ void LoadGlobalReceiver();
// Generate code to push the value of an expression on top of the frame
// and then spill the frame fully to memory. This function is used
Modified: branches/experimental/toiger/src/virtual-frame-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/virtual-frame-ia32.cc (original)
+++ branches/experimental/toiger/src/virtual-frame-ia32.cc Thu Jan 8
06:02:13 2009
@@ -250,10 +250,16 @@
void VirtualFrame::PrepareForCall(int frame_arg_count) {
ASSERT(height() >= frame_arg_count);
- // Below the stack pointer, spill all registers.
+ // Below the stack pointer, spill all registers and make sure that
+ // locals have the right values by sync'ing them. The sync'ing is
+ // necessary to give the debugger a consistent view of the values of
+ // locals in the frame.
for (int i = 0; i <= stack_pointer_; i++) {
- if (elements_[i].is_register()) {
+ FrameElement element = elements_[i];
+ if (element.is_register()) {
SpillElementAt(i);
+ } else if (element.is_valid() && i < expression_base_index()) {
+ SyncElementAt(i);
}
}
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---