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
This commit is contained in:
whesse@chromium.org 2010-07-21 15:16:01 +00:00
parent 9174700dca
commit 8105e9baa3
3 changed files with 88 additions and 107 deletions

View File

@ -4840,8 +4840,13 @@ void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
// Duplicate the object as the IC receiver.
frame_->Dup();
Load(property->value());
frame_->Push(key);
Result ignored = frame_->CallStoreIC();
Result dummy = frame_->CallStoreIC(Handle<String>::cast(key), false);
// 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;
}
// Fall through

View File

@ -997,31 +997,9 @@ void VirtualFrame::SyncRange(int begin, int end) {
}
Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
int arg_count) {
PrepareForCall(arg_count, arg_count);
ASSERT(cgen()->HasValidEntryRegisters());
__ InvokeBuiltin(id, flag);
Result result = cgen()->allocator()->Allocate(rax);
ASSERT(result.is_valid());
return result;
}
//------------------------------------------------------------------------------
// Virtual frame stub and IC calling functions.
Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
RelocInfo::Mode rmode) {
ASSERT(cgen()->HasValidEntryRegisters());
__ Call(code, rmode);
Result result = cgen()->allocator()->Allocate(rax);
ASSERT(result.is_valid());
return result;
}
Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) {
PrepareForCall(arg_count, arg_count);
ASSERT(cgen()->HasValidEntryRegisters());
@ -1053,6 +1031,28 @@ void VirtualFrame::DebugBreak() {
#endif
Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
int arg_count) {
PrepareForCall(arg_count, arg_count);
ASSERT(cgen()->HasValidEntryRegisters());
__ InvokeBuiltin(id, flag);
Result result = cgen()->allocator()->Allocate(rax);
ASSERT(result.is_valid());
return result;
}
Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
RelocInfo::Mode rmode) {
ASSERT(cgen()->HasValidEntryRegisters());
__ Call(code, rmode);
Result result = cgen()->allocator()->Allocate(rax);
ASSERT(result.is_valid());
return result;
}
// This function assumes that the only results that could be in a_reg or b_reg
// are a and b. Other results can be live, but must not be in a_reg or b_reg.
void VirtualFrame::MoveResultsToRegisters(Result* a,
@ -1107,67 +1107,17 @@ Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) {
Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) {
// Key and receiver are on top of the frame. The IC expects them on
// the stack. It does not drop them.
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
Result name = Pop();
// Key and receiver are on top of the frame. Put them in rax and rdx.
Result key = Pop();
Result receiver = Pop();
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);
}
Result VirtualFrame::CallCommonStoreIC(Handle<Code> ic,
Result* value,
Result* key,
Result* receiver) {
// The IC expects value in rax, key in rcx, and receiver in rdx.
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) ||
(value->is_register() && value->reg().is(rax))) {
if (!cgen()->allocator()->is_used(rax)) {
value->ToRegister(rax);
}
MoveResultsToRegisters(key, receiver, rcx, rdx);
value->Unuse();
} else if (!cgen()->allocator()->is_used(rcx) ||
(key->is_register() && key->reg().is(rcx))) {
if (!cgen()->allocator()->is_used(rcx)) {
key->ToRegister(rcx);
}
MoveResultsToRegisters(value, receiver, rax, rdx);
key->Unuse();
} else if (!cgen()->allocator()->is_used(rdx) ||
(receiver->is_register() && receiver->reg().is(rdx))) {
if (!cgen()->allocator()->is_used(rdx)) {
receiver->ToRegister(rdx);
}
MoveResultsToRegisters(key, value, rcx, rax);
receiver->Unuse();
} else {
// Otherwise, no register is free, and no value is in the correct place.
// We have one of the two circular permutations of eax, ecx, edx.
ASSERT(value->is_register());
if (value->reg().is(rcx)) {
__ xchg(rax, rdx);
__ xchg(rax, rcx);
} else {
__ xchg(rax, rcx);
__ 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.
@ -1188,6 +1138,55 @@ Result VirtualFrame::CallStoreIC(Handle<String> name, bool is_contextual) {
}
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);
if (!cgen()->allocator()->is_used(rax) ||
(value.is_register() && value.reg().is(rax))) {
if (!cgen()->allocator()->is_used(rax)) {
value.ToRegister(rax);
}
MoveResultsToRegisters(&key, &receiver, rcx, rdx);
value.Unuse();
} else if (!cgen()->allocator()->is_used(rcx) ||
(key.is_register() && key.reg().is(rcx))) {
if (!cgen()->allocator()->is_used(rcx)) {
key.ToRegister(rcx);
}
MoveResultsToRegisters(&value, &receiver, rax, rdx);
key.Unuse();
} else if (!cgen()->allocator()->is_used(rdx) ||
(receiver.is_register() && receiver.reg().is(rdx))) {
if (!cgen()->allocator()->is_used(rdx)) {
receiver.ToRegister(rdx);
}
MoveResultsToRegisters(&key, &value, rcx, rax);
receiver.Unuse();
} else {
// All three registers are used, and no value is in the correct place.
// We have one of the two circular permutations of rax, rcx, rdx.
ASSERT(value.is_register());
if (value.reg().is(rcx)) {
__ xchg(rax, rdx);
__ xchg(rax, rcx);
} else {
__ xchg(rax, rcx);
__ xchg(rax, rdx);
}
value.Unuse();
key.Unuse();
receiver.Unuse();
}
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
}
Result VirtualFrame::CallCallIC(RelocInfo::Mode mode,
int arg_count,
int loop_nesting) {

View File

@ -329,50 +329,27 @@ class VirtualFrame : public ZoneObject {
int arg_count);
// 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);
// 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);
// 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
// frame. If not, value and receiver are on the frame. Both are dropped.
Result CallStoreIC(Handle<String> name, bool is_contextual);
// Call keyed store IC. Value, key, and receiver are found on top
// of the frame. All are dropped.
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);
}
// of the frame. All three are dropped.
Result CallKeyedStoreIC();
// Call call IC. Function name, arguments, and receiver are found on top
// of the frame and dropped by the call.
// The argument count does not include the receiver.
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);
// Allocate and call JS function as constructor. Arguments,