| Index: src/x64/virtual-frame-x64.cc
|
| ===================================================================
|
| --- src/x64/virtual-frame-x64.cc (revision 5112)
|
| +++ src/x64/virtual-frame-x64.cc (working copy)
|
| @@ -997,60 +997,60 @@
|
| }
|
|
|
|
|
| -Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
|
| - InvokeFlag flag,
|
| - int arg_count) {
|
| +//------------------------------------------------------------------------------
|
| +// Virtual frame stub and IC calling functions.
|
| +
|
| +Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) {
|
| PrepareForCall(arg_count, arg_count);
|
| ASSERT(cgen()->HasValidEntryRegisters());
|
| - __ InvokeBuiltin(id, flag);
|
| + __ CallRuntime(f, arg_count);
|
| 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) {
|
| +Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) {
|
| + PrepareForCall(arg_count, arg_count);
|
| ASSERT(cgen()->HasValidEntryRegisters());
|
| - __ Call(code, rmode);
|
| + __ CallRuntime(id, arg_count);
|
| 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);
|
| +#ifdef ENABLE_DEBUGGER_SUPPORT
|
| +void VirtualFrame::DebugBreak() {
|
| + PrepareForCall(0, 0);
|
| ASSERT(cgen()->HasValidEntryRegisters());
|
| - __ CallRuntime(f, arg_count);
|
| + __ DebugBreak();
|
| Result result = cgen()->allocator()->Allocate(rax);
|
| 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);
|
| ASSERT(cgen()->HasValidEntryRegisters());
|
| - __ CallRuntime(id, arg_count);
|
| + __ InvokeBuiltin(id, flag);
|
| Result result = cgen()->allocator()->Allocate(rax);
|
| ASSERT(result.is_valid());
|
| return result;
|
| }
|
|
|
|
|
| -#ifdef ENABLE_DEBUGGER_SUPPORT
|
| -void VirtualFrame::DebugBreak() {
|
| - PrepareForCall(0, 0);
|
| +Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
|
| + RelocInfo::Mode rmode) {
|
| ASSERT(cgen()->HasValidEntryRegisters());
|
| - __ DebugBreak();
|
| + __ Call(code, rmode);
|
| Result result = cgen()->allocator()->Allocate(rax);
|
| ASSERT(result.is_valid());
|
| + return result;
|
| }
|
| -#endif
|
|
|
|
|
| // This function assumes that the only results that could be in a_reg or b_reg
|
| @@ -1107,87 +1107,86 @@
|
|
|
|
|
| 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.
|
| +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();
|
| + } 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);
|
| - // 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))) {
|
| + (value.is_register() && value.reg().is(rax))) {
|
| if (!cgen()->allocator()->is_used(rax)) {
|
| - value->ToRegister(rax);
|
| + value.ToRegister(rax);
|
| }
|
| - MoveResultsToRegisters(key, receiver, rcx, rdx);
|
| - value->Unuse();
|
| + MoveResultsToRegisters(&key, &receiver, rcx, rdx);
|
| + value.Unuse();
|
| } 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)) {
|
| - key->ToRegister(rcx);
|
| + key.ToRegister(rcx);
|
| }
|
| - MoveResultsToRegisters(value, receiver, rax, rdx);
|
| - key->Unuse();
|
| + MoveResultsToRegisters(&value, &receiver, rax, rdx);
|
| + key.Unuse();
|
| } 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)) {
|
| - receiver->ToRegister(rdx);
|
| + receiver.ToRegister(rdx);
|
| }
|
| - MoveResultsToRegisters(key, value, rcx, rax);
|
| - receiver->Unuse();
|
| + 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)) {
|
| + // 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();
|
| + value.Unuse();
|
| + key.Unuse();
|
| + receiver.Unuse();
|
| }
|
|
|
| + Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
| 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();
|
| - } else {
|
| - Result receiver = Pop();
|
| - PrepareForCall(0, 0);
|
| - MoveResultsToRegisters(&value, &receiver, rax, rdx);
|
| - }
|
| - __ Move(rcx, name);
|
| - return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
|
| -}
|
| -
|
| -
|
| Result VirtualFrame::CallCallIC(RelocInfo::Mode mode,
|
| int arg_count,
|
| int loop_nesting) {
|
|
|