| Index: src/arm/full-codegen-arm.cc
|
| ===================================================================
|
| --- src/arm/full-codegen-arm.cc (revision 5846)
|
| +++ src/arm/full-codegen-arm.cc (working copy)
|
| @@ -36,6 +36,7 @@
|
| #include "full-codegen.h"
|
| #include "parser.h"
|
| #include "scopes.h"
|
| +#include "stub-cache.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -171,19 +172,16 @@
|
| }
|
|
|
| // Check the stack for overflow or break request.
|
| - // Put the lr setup instruction in the delay slot. The kInstrSize is
|
| - // added to the implicit 8 byte offset that always applies to operations
|
| - // with pc and gives a return address 12 bytes down.
|
| { Comment cmnt(masm_, "[ Stack check");
|
| __ LoadRoot(r2, Heap::kStackLimitRootIndex);
|
| - __ add(lr, pc, Operand(Assembler::kInstrSize));
|
| __ cmp(sp, Operand(r2));
|
| StackCheckStub stub;
|
| - __ mov(pc,
|
| + __ mov(ip,
|
| Operand(reinterpret_cast<intptr_t>(stub.GetCode().location()),
|
| RelocInfo::CODE_TARGET),
|
| LeaveCC,
|
| lo);
|
| + __ Call(ip, lo);
|
| }
|
|
|
| if (FLAG_trace) {
|
| @@ -1019,7 +1017,7 @@
|
| __ bind(&fast);
|
| }
|
|
|
| - __ ldr(r0, CodeGenerator::GlobalObject());
|
| + __ ldr(r0, GlobalObjectOperand());
|
| __ mov(r2, Operand(slot->var()->name()));
|
| RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
|
| ? RelocInfo::CODE_TARGET
|
| @@ -1040,7 +1038,7 @@
|
| Comment cmnt(masm_, "Global variable");
|
| // Use inline caching. Variable name is passed in r2 and the global
|
| // object (receiver) in r0.
|
| - __ ldr(r0, CodeGenerator::GlobalObject());
|
| + __ ldr(r0, GlobalObjectOperand());
|
| __ mov(r2, Operand(var->name()));
|
| Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
| EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
|
| @@ -1514,7 +1512,7 @@
|
| // assignment. Right-hand-side value is passed in r0, variable name in
|
| // r2, and the global object in r1.
|
| __ mov(r2, Operand(var->name()));
|
| - __ ldr(r1, CodeGenerator::GlobalObject());
|
| + __ ldr(r1, GlobalObjectOperand());
|
| Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
| EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
|
|
| @@ -1698,7 +1696,7 @@
|
| SetSourcePosition(expr->position(), FORCED_POSITION);
|
| // Call the IC initialization code.
|
| InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
| - Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
|
| + Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop);
|
| EmitCallIC(ic, mode);
|
| // Restore context register.
|
| __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
| @@ -1709,6 +1707,15 @@
|
| void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
|
| Expression* key,
|
| RelocInfo::Mode mode) {
|
| + // Load the key.
|
| + VisitForAccumulatorValue(key);
|
| +
|
| + // Swap the name of the function and the receiver on the stack to follow
|
| + // the calling convention for call ICs.
|
| + __ pop(r1);
|
| + __ push(r0);
|
| + __ push(r1);
|
| +
|
| // Code common for calls using the IC.
|
| ZoneList<Expression*>* args = expr->arguments();
|
| int arg_count = args->length();
|
| @@ -1716,19 +1723,17 @@
|
| for (int i = 0; i < arg_count; i++) {
|
| VisitForStackValue(args->at(i));
|
| }
|
| - VisitForAccumulatorValue(key);
|
| - __ mov(r2, r0);
|
| }
|
| // Record source position for debugger.
|
| SetSourcePosition(expr->position(), FORCED_POSITION);
|
| // Call the IC initialization code.
|
| InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
| - Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count,
|
| - in_loop);
|
| + Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arg_count, in_loop);
|
| + __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key.
|
| EmitCallIC(ic, mode);
|
| // Restore context register.
|
| __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
| - context()->Plug(r0);
|
| + context()->DropAndPlug(1, r0); // Drop the key still on the stack.
|
| }
|
|
|
|
|
| @@ -1809,7 +1814,7 @@
|
| context()->DropAndPlug(1, r0);
|
| } else if (var != NULL && !var->is_this() && var->is_global()) {
|
| // Push global object as receiver for the call IC.
|
| - __ ldr(r0, CodeGenerator::GlobalObject());
|
| + __ ldr(r0, GlobalObjectOperand());
|
| __ push(r0);
|
| EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
|
| } else if (var != NULL && var->AsSlot() != NULL &&
|
| @@ -1845,7 +1850,7 @@
|
| // Push function.
|
| __ push(r0);
|
| // Push global receiver.
|
| - __ ldr(r1, CodeGenerator::GlobalObject());
|
| + __ ldr(r1, GlobalObjectOperand());
|
| __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
|
| __ push(r1);
|
| __ bind(&call);
|
| @@ -1879,7 +1884,7 @@
|
|
|
| Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
| EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
| - __ ldr(r1, CodeGenerator::GlobalObject());
|
| + __ ldr(r1, GlobalObjectOperand());
|
| __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
|
| __ Push(r0, r1); // Function, receiver.
|
| EmitCallWithStub(expr);
|
| @@ -1902,7 +1907,7 @@
|
| VisitForStackValue(fun);
|
| }
|
| // Load global receiver object.
|
| - __ ldr(r1, CodeGenerator::GlobalObject());
|
| + __ ldr(r1, GlobalObjectOperand());
|
| __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
|
| __ push(r1);
|
| // Emit function call.
|
| @@ -2780,7 +2785,7 @@
|
|
|
| if (expr->is_jsruntime()) {
|
| // Prepare for calling JS runtime function.
|
| - __ ldr(r0, CodeGenerator::GlobalObject());
|
| + __ ldr(r0, GlobalObjectOperand());
|
| __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset));
|
| __ push(r0);
|
| }
|
| @@ -2794,8 +2799,7 @@
|
| if (expr->is_jsruntime()) {
|
| // Call the JS runtime function.
|
| __ mov(r2, Operand(expr->name()));
|
| - Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
|
| - NOT_IN_LOOP);
|
| + Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, NOT_IN_LOOP);
|
| EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
| // Restore context register.
|
| __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
| @@ -2832,7 +2836,7 @@
|
| VisitForStackValue(prop->obj());
|
| VisitForStackValue(prop->key());
|
| } else if (var->is_global()) {
|
| - __ ldr(r1, CodeGenerator::GlobalObject());
|
| + __ ldr(r1, GlobalObjectOperand());
|
| __ mov(r0, Operand(var->name()));
|
| __ Push(r1, r0);
|
| } else {
|
| @@ -3098,7 +3102,7 @@
|
| VariableProxy* proxy = expr->AsVariableProxy();
|
| if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
|
| Comment cmnt(masm_, "Global variable");
|
| - __ ldr(r0, CodeGenerator::GlobalObject());
|
| + __ ldr(r0, GlobalObjectOperand());
|
| __ mov(r2, Operand(proxy->name()));
|
| Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
| // Use a regular load, not a contextual load, to avoid a reference
|
|
|