| Index: src/arm/macro-assembler-arm.cc
|
| diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
|
| index 83b9b9bebe59c03ea15d2c5e98b9aaf5de8c2662..1be0b746f91d7b0fb8692a36c17721145cb6d720 100644
|
| --- a/src/arm/macro-assembler-arm.cc
|
| +++ b/src/arm/macro-assembler-arm.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:
|
| @@ -171,13 +171,6 @@ void MacroAssembler::Ret(Condition cond) {
|
| }
|
|
|
|
|
| -void MacroAssembler::StackLimitCheck(Label* on_stack_overflow) {
|
| - LoadRoot(ip, Heap::kStackLimitRootIndex);
|
| - cmp(sp, Operand(ip));
|
| - b(lo, on_stack_overflow);
|
| -}
|
| -
|
| -
|
| void MacroAssembler::Drop(int count, Condition cond) {
|
| if (count > 0) {
|
| add(sp, sp, Operand(count * kPointerSize), LeaveCC, cond);
|
| @@ -447,6 +440,34 @@ void MacroAssembler::RecordWrite(Register object,
|
| }
|
|
|
|
|
| +// Push and pop all registers that can hold pointers.
|
| +void MacroAssembler::PushSafepointRegisters() {
|
| + // Safepoints expect a block of contiguous register values starting with r0:
|
| + ASSERT(((1 << kNumSafepointSavedRegisters) - 1) == kSafepointSavedRegisters);
|
| + // Safepoints expect a block of kNumSafepointRegisters values on the
|
| + // stack, so adjust the stack for unsaved registers.
|
| + const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters;
|
| + ASSERT(num_unsaved >= 0);
|
| + sub(sp, sp, Operand(num_unsaved * kPointerSize));
|
| + stm(db_w, sp, kSafepointSavedRegisters);
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::PopSafepointRegisters() {
|
| + const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters;
|
| + ldm(ia_w, sp, kSafepointSavedRegisters);
|
| + add(sp, sp, Operand(num_unsaved * kPointerSize));
|
| +}
|
| +
|
| +
|
| +int MacroAssembler::SafepointRegisterStackIndex(int reg_code) {
|
| + // The registers are pushed starting with the highest encoding,
|
| + // which means that lowest encodings are closest to the stack pointer.
|
| + ASSERT(reg_code >= 0 && reg_code < kNumSafepointRegisters);
|
| + return reg_code;
|
| +}
|
| +
|
| +
|
| void MacroAssembler::Ldrd(Register dst1, Register dst2,
|
| const MemOperand& src, Condition cond) {
|
| ASSERT(src.rm().is(no_reg));
|
| @@ -515,12 +536,8 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) {
|
| }
|
|
|
|
|
| -void MacroAssembler::EnterExitFrame() {
|
| - // Compute the argv pointer and keep it in a callee-saved register.
|
| +void MacroAssembler::EnterExitFrame(bool save_doubles) {
|
| // r0 is argc.
|
| - add(r6, sp, Operand(r0, LSL, kPointerSizeLog2));
|
| - sub(r6, r6, Operand(kPointerSize));
|
| -
|
| // Compute callee's stack pointer before making changes and save it as
|
| // ip register so that it is restored as sp register on exit, thereby
|
| // popping the args.
|
| @@ -528,6 +545,9 @@ void MacroAssembler::EnterExitFrame() {
|
| // ip = sp + kPointerSize * #args;
|
| add(ip, sp, Operand(r0, LSL, kPointerSizeLog2));
|
|
|
| + // Compute the argv pointer and keep it in a callee-saved register.
|
| + sub(r6, ip, Operand(kPointerSize));
|
| +
|
| // Prepare the stack to be aligned when calling into C. After this point there
|
| // are 5 pushes before the call into C, so the stack needs to be aligned after
|
| // 5 pushes.
|
| @@ -558,6 +578,28 @@ void MacroAssembler::EnterExitFrame() {
|
| // Setup argc and the builtin function in callee-saved registers.
|
| mov(r4, Operand(r0));
|
| mov(r5, Operand(r1));
|
| +
|
| + // Optionally save all double registers.
|
| + if (save_doubles) {
|
| + // TODO(regis): Use vstrm instruction.
|
| + // The stack alignment code above made sp unaligned, so add space for one
|
| + // more double register and use aligned addresses.
|
| + ASSERT(kDoubleSize == frame_alignment);
|
| + // Mark the frame as containing doubles by pushing a non-valid return
|
| + // address, i.e. 0.
|
| + ASSERT(ExitFrameConstants::kMarkerOffset == -2 * kPointerSize);
|
| + mov(ip, Operand(0)); // Marker and alignment word.
|
| + push(ip);
|
| + int space = DwVfpRegister::kNumRegisters * kDoubleSize + kPointerSize;
|
| + sub(sp, sp, Operand(space));
|
| + for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) {
|
| + DwVfpRegister reg = DwVfpRegister::from_code(i);
|
| + vstr(reg, sp, i * kDoubleSize + kPointerSize);
|
| + }
|
| + // Note that d0 will be accessible at fp - 2*kPointerSize -
|
| + // DwVfpRegister::kNumRegisters * kDoubleSize, since the code slot and the
|
| + // alignment word were pushed after the fp.
|
| + }
|
| }
|
|
|
|
|
| @@ -592,7 +634,18 @@ int MacroAssembler::ActivationFrameAlignment() {
|
| }
|
|
|
|
|
| -void MacroAssembler::LeaveExitFrame() {
|
| +void MacroAssembler::LeaveExitFrame(bool save_doubles) {
|
| + // Optionally restore all double registers.
|
| + if (save_doubles) {
|
| + // TODO(regis): Use vldrm instruction.
|
| + for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) {
|
| + DwVfpRegister reg = DwVfpRegister::from_code(i);
|
| + // Register d15 is just below the marker.
|
| + const int offset = ExitFrameConstants::kMarkerOffset;
|
| + vldr(reg, fp, (i - DwVfpRegister::kNumRegisters) * kDoubleSize + offset);
|
| + }
|
| + }
|
| +
|
| // Clear top frame.
|
| mov(r3, Operand(0, RelocInfo::NONE));
|
| mov(ip, Operand(ExternalReference(Isolate::k_c_entry_fp_address)));
|
| @@ -757,7 +810,15 @@ void MacroAssembler::InvokeFunction(JSFunction* function,
|
| // 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.
|
| + ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
|
| + InvokeCode(r3, expected, actual, flag);
|
| + } else {
|
| + InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag);
|
| + }
|
| }
|
|
|
|
|
| @@ -1516,6 +1577,16 @@ void MacroAssembler::CallRuntime(Runtime::FunctionId fid, int num_arguments) {
|
| }
|
|
|
|
|
| +void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) {
|
| + const Runtime::Function* function = Runtime::FunctionForId(id);
|
| + mov(r0, Operand(function->nargs));
|
| + mov(r1, Operand(ExternalReference(function)));
|
| + CEntryStub stub(1);
|
| + stub.SaveDoubles();
|
| + CallStub(&stub);
|
| +}
|
| +
|
| +
|
| void MacroAssembler::CallExternalReference(const ExternalReference& ext,
|
| int num_arguments) {
|
| mov(r0, Operand(num_arguments));
|
|
|