| Index: src/ia32/macro-assembler-ia32.cc
|
| diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
|
| index 038efdeef65183fd17956fc8bbce4cec108d87a0..ea0c5943710a274595254ce31293f7b401678b27 100644
|
| --- a/src/ia32/macro-assembler-ia32.cc
|
| +++ b/src/ia32/macro-assembler-ia32.cc
|
| @@ -1,4 +1,4 @@
|
| -// Copyright 2006-2009 the V8 project authors. All rights reserved.
|
| +// Copyright 2010 the V8 project authors. All rights reserved.
|
| // Redistribution and use in source and binary forms, with or without
|
| // modification, are permitted provided that the following conditions are
|
| // met:
|
| @@ -183,13 +183,6 @@ void MacroAssembler::RecordWrite(Register object,
|
| }
|
|
|
|
|
| -void MacroAssembler::StackLimitCheck(Label* on_stack_overflow) {
|
| - cmp(esp,
|
| - Operand::StaticVariable(ExternalReference::address_of_stack_limit()));
|
| - j(below, on_stack_overflow);
|
| -}
|
| -
|
| -
|
| #ifdef ENABLE_DEBUGGER_SUPPORT
|
| void MacroAssembler::DebugBreak() {
|
| Set(eax, Immediate(0));
|
| @@ -364,9 +357,20 @@ void MacroAssembler::EnterExitFramePrologue() {
|
| }
|
|
|
|
|
| -void MacroAssembler::EnterExitFrameEpilogue(int argc) {
|
| - // Reserve space for arguments.
|
| - sub(Operand(esp), Immediate(argc * kPointerSize));
|
| +void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) {
|
| + // Optionally save all XMM registers.
|
| + if (save_doubles) {
|
| + CpuFeatures::Scope scope(SSE2);
|
| + int space = XMMRegister::kNumRegisters * kDoubleSize + argc * kPointerSize;
|
| + sub(Operand(esp), Immediate(space));
|
| + int offset = -2 * kPointerSize;
|
| + for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
|
| + XMMRegister reg = XMMRegister::from_code(i);
|
| + movdbl(Operand(ebp, offset - ((i + 1) * kDoubleSize)), reg);
|
| + }
|
| + } else {
|
| + sub(Operand(esp), Immediate(argc * kPointerSize));
|
| + }
|
|
|
| // Get the required frame alignment for the OS.
|
| const int kFrameAlignment = OS::ActivationFrameAlignment();
|
| @@ -380,7 +384,7 @@ void MacroAssembler::EnterExitFrameEpilogue(int argc) {
|
| }
|
|
|
|
|
| -void MacroAssembler::EnterExitFrame() {
|
| +void MacroAssembler::EnterExitFrame(bool save_doubles) {
|
| EnterExitFramePrologue();
|
|
|
| // Setup argc and argv in callee-saved registers.
|
| @@ -389,17 +393,27 @@ void MacroAssembler::EnterExitFrame() {
|
| lea(esi, Operand(ebp, eax, times_4, offset));
|
|
|
| // Reserve space for argc, argv and isolate.
|
| - EnterExitFrameEpilogue(3);
|
| + EnterExitFrameEpilogue(3, save_doubles);
|
| }
|
|
|
|
|
| void MacroAssembler::EnterApiExitFrame(int argc) {
|
| EnterExitFramePrologue();
|
| - EnterExitFrameEpilogue(argc);
|
| + EnterExitFrameEpilogue(argc, false);
|
| }
|
|
|
|
|
| -void MacroAssembler::LeaveExitFrame() {
|
| +void MacroAssembler::LeaveExitFrame(bool save_doubles) {
|
| + // Optionally restore all XMM registers.
|
| + if (save_doubles) {
|
| + CpuFeatures::Scope scope(SSE2);
|
| + int offset = -2 * kPointerSize;
|
| + for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
|
| + XMMRegister reg = XMMRegister::from_code(i);
|
| + movdbl(reg, Operand(ebp, offset - ((i + 1) * kDoubleSize)));
|
| + }
|
| + }
|
| +
|
| // Get the return address from the stack and restore the frame pointer.
|
| mov(ecx, Operand(ebp, 1 * kPointerSize));
|
| mov(ebp, Operand(ebp, 0 * kPointerSize));
|
| @@ -1100,6 +1114,16 @@ void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) {
|
| }
|
|
|
|
|
| +void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) {
|
| + const Runtime::Function* function = Runtime::FunctionForId(id);
|
| + Set(eax, Immediate(function->nargs));
|
| + mov(ebx, Immediate(ExternalReference(function)));
|
| + CEntryStub ces(1);
|
| + ces.SaveDoubles();
|
| + CallStub(&ces);
|
| +}
|
| +
|
| +
|
| MaybeObject* MacroAssembler::TryCallRuntime(Runtime::FunctionId id,
|
| int num_arguments) {
|
| return TryCallRuntime(Runtime::FunctionForId(id), num_arguments);
|
| @@ -1340,7 +1364,8 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
|
| Handle<Code> code_constant,
|
| const Operand& code_operand,
|
| Label* done,
|
| - InvokeFlag flag) {
|
| + InvokeFlag flag,
|
| + PostCallGenerator* post_call_generator) {
|
| bool definitely_matches = false;
|
| Label invoke;
|
| if (expected.is_immediate()) {
|
| @@ -1392,6 +1417,7 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
|
|
|
| if (flag == CALL_FUNCTION) {
|
| call(adaptor, RelocInfo::CODE_TARGET);
|
| + if (post_call_generator != NULL) post_call_generator->Generate();
|
| jmp(done);
|
| } else {
|
| jmp(adaptor, RelocInfo::CODE_TARGET);
|
| @@ -1404,11 +1430,14 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
|
| void MacroAssembler::InvokeCode(const Operand& code,
|
| const ParameterCount& expected,
|
| const ParameterCount& actual,
|
| - InvokeFlag flag) {
|
| + InvokeFlag flag,
|
| + PostCallGenerator* post_call_generator) {
|
| Label done;
|
| - InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag);
|
| + InvokePrologue(expected, actual, Handle<Code>::null(), code,
|
| + &done, flag, post_call_generator);
|
| if (flag == CALL_FUNCTION) {
|
| call(code);
|
| + if (post_call_generator != NULL) post_call_generator->Generate();
|
| } else {
|
| ASSERT(flag == JUMP_FUNCTION);
|
| jmp(code);
|
| @@ -1421,12 +1450,15 @@ void MacroAssembler::InvokeCode(Handle<Code> code,
|
| const ParameterCount& expected,
|
| const ParameterCount& actual,
|
| RelocInfo::Mode rmode,
|
| - InvokeFlag flag) {
|
| + InvokeFlag flag,
|
| + PostCallGenerator* post_call_generator) {
|
| Label done;
|
| Operand dummy(eax);
|
| - InvokePrologue(expected, actual, code, dummy, &done, flag);
|
| + InvokePrologue(expected, actual, code, dummy, &done,
|
| + flag, post_call_generator);
|
| if (flag == CALL_FUNCTION) {
|
| call(code, rmode);
|
| + if (post_call_generator != NULL) post_call_generator->Generate();
|
| } else {
|
| ASSERT(flag == JUMP_FUNCTION);
|
| jmp(code, rmode);
|
| @@ -1437,7 +1469,8 @@ void MacroAssembler::InvokeCode(Handle<Code> code,
|
|
|
| void MacroAssembler::InvokeFunction(Register fun,
|
| const ParameterCount& actual,
|
| - InvokeFlag flag) {
|
| + InvokeFlag flag,
|
| + PostCallGenerator* post_call_generator) {
|
| ASSERT(fun.is(edi));
|
| mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
|
| mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
|
| @@ -1446,25 +1479,37 @@ void MacroAssembler::InvokeFunction(Register fun,
|
|
|
| ParameterCount expected(ebx);
|
| InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
|
| - expected, actual, flag);
|
| + expected, actual, flag, post_call_generator);
|
| }
|
|
|
|
|
| void MacroAssembler::InvokeFunction(JSFunction* function,
|
| const ParameterCount& actual,
|
| - InvokeFlag flag) {
|
| + InvokeFlag flag,
|
| + PostCallGenerator* post_call_generator) {
|
| ASSERT(function->is_compiled());
|
| // Get the function and setup the context.
|
| mov(edi, Immediate(Handle<JSFunction>(function)));
|
| mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
|
| - // Invoke the cached code.
|
| - Handle<Code> code(function->code());
|
| +
|
| ParameterCount expected(function->shared()->formal_parameter_count());
|
| - InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag);
|
| + if (V8::UseCrankshaft()) {
|
| + // TODO(kasperl): For now, we always call indirectly through the
|
| + // code field in the function to allow recompilation to take effect
|
| + // without changing any of the call sites.
|
| + InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
|
| + expected, actual, flag, post_call_generator);
|
| + } else {
|
| + Handle<Code> code(function->code());
|
| + InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET,
|
| + flag, post_call_generator);
|
| + }
|
| }
|
|
|
|
|
| -void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
|
| +void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
|
| + InvokeFlag flag,
|
| + PostCallGenerator* post_call_generator) {
|
| // Calls are not allowed in some stubs.
|
| ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
|
|
|
| @@ -1474,7 +1519,7 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
|
| ParameterCount expected(0);
|
| GetBuiltinFunction(edi, id);
|
| InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
|
| - expected, expected, flag);
|
| + expected, expected, flag, post_call_generator);
|
| }
|
|
|
| void MacroAssembler::GetBuiltinFunction(Register target,
|
| @@ -1539,6 +1584,15 @@ void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
|
| }
|
|
|
|
|
| +int MacroAssembler::SafepointRegisterStackIndex(int reg_code) {
|
| + // The registers are pushed starting with the lowest encoding,
|
| + // which means that lowest encodings are furthest away from
|
| + // the stack pointer.
|
| + ASSERT(reg_code >= 0 && reg_code < kNumSafepointRegisters);
|
| + return kNumSafepointRegisters - reg_code - 1;
|
| +}
|
| +
|
| +
|
| void MacroAssembler::Ret() {
|
| ret(0);
|
| }
|
|
|