Commit 8105e9ba authored by whesse@chromium.org's avatar whesse@chromium.org

Remove VirtualFrame::CallStoreIC(void) and CallCommonStoreIC from...

Remove VirtualFrame::CallStoreIC(void) and CallCommonStoreIC from virtual-frame-x64.cc.  Make implementations of CallStoreIC(key, is_contextual) and CallKeyedStoreIC() the same on x64 and ia32.  Make ia32 and x64 implementations more alike by moving some functions and changing comments. 
Review URL: http://codereview.chromium.org/3060002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5113 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 9174700d
...@@ -4840,8 +4840,13 @@ void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { ...@@ -4840,8 +4840,13 @@ void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
// Duplicate the object as the IC receiver. // Duplicate the object as the IC receiver.
frame_->Dup(); frame_->Dup();
Load(property->value()); Load(property->value());
frame_->Push(key); Result dummy = frame_->CallStoreIC(Handle<String>::cast(key), false);
Result ignored = frame_->CallStoreIC(); // A test eax instruction following the store IC call would
// indicate the presence of an inlined version of the
// store. Add a nop to indicate that there is no such
// inlined version.
__ nop();
dummy.Unuse();
break; break;
} }
// Fall through // Fall through
......
...@@ -997,60 +997,60 @@ void VirtualFrame::SyncRange(int begin, int end) { ...@@ -997,60 +997,60 @@ void VirtualFrame::SyncRange(int begin, int end) {
} }
Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id, //------------------------------------------------------------------------------
InvokeFlag flag, // Virtual frame stub and IC calling functions.
int arg_count) {
Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) {
PrepareForCall(arg_count, arg_count); PrepareForCall(arg_count, arg_count);
ASSERT(cgen()->HasValidEntryRegisters()); ASSERT(cgen()->HasValidEntryRegisters());
__ InvokeBuiltin(id, flag); __ CallRuntime(f, arg_count);
Result result = cgen()->allocator()->Allocate(rax); Result result = cgen()->allocator()->Allocate(rax);
ASSERT(result.is_valid()); ASSERT(result.is_valid());
return result; return result;
} }
//------------------------------------------------------------------------------ Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) {
// Virtual frame stub and IC calling functions. PrepareForCall(arg_count, arg_count);
Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
RelocInfo::Mode rmode) {
ASSERT(cgen()->HasValidEntryRegisters()); ASSERT(cgen()->HasValidEntryRegisters());
__ Call(code, rmode); __ CallRuntime(id, arg_count);
Result result = cgen()->allocator()->Allocate(rax); Result result = cgen()->allocator()->Allocate(rax);
ASSERT(result.is_valid()); ASSERT(result.is_valid());
return result; return result;
} }
Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) { #ifdef ENABLE_DEBUGGER_SUPPORT
PrepareForCall(arg_count, arg_count); void VirtualFrame::DebugBreak() {
PrepareForCall(0, 0);
ASSERT(cgen()->HasValidEntryRegisters()); ASSERT(cgen()->HasValidEntryRegisters());
__ CallRuntime(f, arg_count); __ DebugBreak();
Result result = cgen()->allocator()->Allocate(rax); Result result = cgen()->allocator()->Allocate(rax);
ASSERT(result.is_valid()); ASSERT(result.is_valid());
return result;
} }
#endif
Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) { Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
int arg_count) {
PrepareForCall(arg_count, arg_count); PrepareForCall(arg_count, arg_count);
ASSERT(cgen()->HasValidEntryRegisters()); ASSERT(cgen()->HasValidEntryRegisters());
__ CallRuntime(id, arg_count); __ InvokeBuiltin(id, flag);
Result result = cgen()->allocator()->Allocate(rax); Result result = cgen()->allocator()->Allocate(rax);
ASSERT(result.is_valid()); ASSERT(result.is_valid());
return result; return result;
} }
#ifdef ENABLE_DEBUGGER_SUPPORT Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
void VirtualFrame::DebugBreak() { RelocInfo::Mode rmode) {
PrepareForCall(0, 0);
ASSERT(cgen()->HasValidEntryRegisters()); ASSERT(cgen()->HasValidEntryRegisters());
__ DebugBreak(); __ Call(code, rmode);
Result result = cgen()->allocator()->Allocate(rax); Result result = cgen()->allocator()->Allocate(rax);
ASSERT(result.is_valid()); ASSERT(result.is_valid());
return result;
} }
#endif
// This function assumes that the only results that could be in a_reg or b_reg // This function assumes that the only results that could be in a_reg or b_reg
...@@ -1107,83 +1107,82 @@ Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) { ...@@ -1107,83 +1107,82 @@ Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) {
Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) { Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) {
// Key and receiver are on top of the frame. The IC expects them on // Key and receiver are on top of the frame. Put them in rax and rdx.
// the stack. It does not drop them. Result key = Pop();
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
Result name = Pop();
Result receiver = Pop(); Result receiver = Pop();
PrepareForCall(0, 0); PrepareForCall(0, 0);
MoveResultsToRegisters(&name, &receiver, rax, rdx); MoveResultsToRegisters(&key, &receiver, rax, rdx);
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
return RawCallCodeObject(ic, mode); return RawCallCodeObject(ic, mode);
} }
Result VirtualFrame::CallCommonStoreIC(Handle<Code> ic, Result VirtualFrame::CallStoreIC(Handle<String> name, bool is_contextual) {
Result* value, // Value and (if not contextual) receiver are on top of the frame.
Result* key, // The IC expects name in rcx, value in rax, and receiver in rdx.
Result* receiver) { Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
// The IC expects value in rax, key in rcx, and receiver in rdx. Result value = Pop();
if (is_contextual) {
PrepareForCall(0, 0);
value.ToRegister(rax);
__ movq(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
value.Unuse();
} else {
Result receiver = Pop();
PrepareForCall(0, 0);
MoveResultsToRegisters(&value, &receiver, rax, rdx);
}
__ Move(rcx, name);
return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
}
Result VirtualFrame::CallKeyedStoreIC() {
// Value, key, and receiver are on the top of the frame. The IC
// expects value in rax, key in rcx, and receiver in rdx.
Result value = Pop();
Result key = Pop();
Result receiver = Pop();
PrepareForCall(0, 0); PrepareForCall(0, 0);
// If one of the three registers is free, or a value is already
// in the correct register, move the remaining two values using
// MoveResultsToRegisters().
if (!cgen()->allocator()->is_used(rax) || if (!cgen()->allocator()->is_used(rax) ||
(value->is_register() && value->reg().is(rax))) { (value.is_register() && value.reg().is(rax))) {
if (!cgen()->allocator()->is_used(rax)) { if (!cgen()->allocator()->is_used(rax)) {
value->ToRegister(rax); value.ToRegister(rax);
} }
MoveResultsToRegisters(key, receiver, rcx, rdx); MoveResultsToRegisters(&key, &receiver, rcx, rdx);
value->Unuse(); value.Unuse();
} else if (!cgen()->allocator()->is_used(rcx) || } else if (!cgen()->allocator()->is_used(rcx) ||
(key->is_register() && key->reg().is(rcx))) { (key.is_register() && key.reg().is(rcx))) {
if (!cgen()->allocator()->is_used(rcx)) { if (!cgen()->allocator()->is_used(rcx)) {
key->ToRegister(rcx); key.ToRegister(rcx);
} }
MoveResultsToRegisters(value, receiver, rax, rdx); MoveResultsToRegisters(&value, &receiver, rax, rdx);
key->Unuse(); key.Unuse();
} else if (!cgen()->allocator()->is_used(rdx) || } else if (!cgen()->allocator()->is_used(rdx) ||
(receiver->is_register() && receiver->reg().is(rdx))) { (receiver.is_register() && receiver.reg().is(rdx))) {
if (!cgen()->allocator()->is_used(rdx)) { if (!cgen()->allocator()->is_used(rdx)) {
receiver->ToRegister(rdx); receiver.ToRegister(rdx);
} }
MoveResultsToRegisters(key, value, rcx, rax); MoveResultsToRegisters(&key, &value, rcx, rax);
receiver->Unuse(); receiver.Unuse();
} else { } else {
// Otherwise, no register is free, and no value is in the correct place. // All three registers are used, and no value is in the correct place.
// We have one of the two circular permutations of eax, ecx, edx. // We have one of the two circular permutations of rax, rcx, rdx.
ASSERT(value->is_register()); ASSERT(value.is_register());
if (value->reg().is(rcx)) { if (value.reg().is(rcx)) {
__ xchg(rax, rdx); __ xchg(rax, rdx);
__ xchg(rax, rcx); __ xchg(rax, rcx);
} else { } else {
__ xchg(rax, rcx); __ xchg(rax, rcx);
__ xchg(rax, rdx); __ xchg(rax, rdx);
} }
value->Unuse();
key->Unuse();
receiver->Unuse();
}
return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
}
Result VirtualFrame::CallStoreIC(Handle<String> name, bool is_contextual) {
// Value and (if not contextual) receiver are on top of the frame.
// The IC expects name in rcx, value in rax, and receiver in rdx.
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
Result value = Pop();
if (is_contextual) {
PrepareForCall(0, 0);
value.ToRegister(rax);
__ movq(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
value.Unuse(); value.Unuse();
} else { key.Unuse();
Result receiver = Pop(); receiver.Unuse();
PrepareForCall(0, 0);
MoveResultsToRegisters(&value, &receiver, rax, rdx);
} }
__ Move(rcx, name);
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
} }
......
...@@ -329,50 +329,27 @@ class VirtualFrame : public ZoneObject { ...@@ -329,50 +329,27 @@ class VirtualFrame : public ZoneObject {
int arg_count); int arg_count);
// Call load IC. Name and receiver are found on top of the frame. // Call load IC. Name and receiver are found on top of the frame.
// Receiver is not dropped. // Both are dropped.
Result CallLoadIC(RelocInfo::Mode mode); Result CallLoadIC(RelocInfo::Mode mode);
// Call keyed load IC. Key and receiver are found on top of the // Call keyed load IC. Key and receiver are found on top of the
// frame. They are not dropped. // frame. Both are dropped.
Result CallKeyedLoadIC(RelocInfo::Mode mode); Result CallKeyedLoadIC(RelocInfo::Mode mode);
// Calling a store IC and a keyed store IC differ only by which ic is called
// and by the order of the three arguments on the frame.
Result CallCommonStoreIC(Handle<Code> ic,
Result* value,
Result* key,
Result* receiver);
// Call store IC. Name, value, and receiver are found on top
// of the frame. All are dropped.
Result CallStoreIC() {
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
Result name = Pop();
Result value = Pop();
Result receiver = Pop();
return CallCommonStoreIC(ic, &value, &name, &receiver);
}
// Call store IC. If the load is contextual, value is found on top of the // Call store IC. If the load is contextual, value is found on top of the
// frame. If not, value and receiver are on the frame. Both are dropped. // frame. If not, value and receiver are on the frame. Both are dropped.
Result CallStoreIC(Handle<String> name, bool is_contextual); Result CallStoreIC(Handle<String> name, bool is_contextual);
// Call keyed store IC. Value, key, and receiver are found on top // Call keyed store IC. Value, key, and receiver are found on top
// of the frame. All are dropped. // of the frame. All three are dropped.
Result CallKeyedStoreIC() { Result CallKeyedStoreIC();
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
Result value = Pop();
Result key = Pop();
Result receiver = Pop();
return CallCommonStoreIC(ic, &value, &key, &receiver);
}
// Call call IC. Function name, arguments, and receiver are found on top // Call call IC. Function name, arguments, and receiver are found on top
// of the frame and dropped by the call. // of the frame and dropped by the call.
// The argument count does not include the receiver. // The argument count does not include the receiver.
Result CallCallIC(RelocInfo::Mode mode, int arg_count, int loop_nesting); Result CallCallIC(RelocInfo::Mode mode, int arg_count, int loop_nesting);
// Call keyed call IC. Same calling convention as CallCallIC.
Result CallKeyedCallIC(RelocInfo::Mode mode, int arg_count, int loop_nesting); Result CallKeyedCallIC(RelocInfo::Mode mode, int arg_count, int loop_nesting);
// Allocate and call JS function as constructor. Arguments, // Allocate and call JS function as constructor. Arguments,
......
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