Push version 2.5.7 to trunk.
Fixed obscure evaluation order bug (issue 931).
Split the random number state between JavaScript and the private API.
Fixed performance bug causing GCs when generating stack traces on
code from very large scripts.
Fixed bug in parser that allowed (foo):42 as a labelled statement
(issue 918).
Provide more accurate results about used heap size via
GetHeapStatistics.
Allow build-time customization of the max semispace size.
Made String.prototype.split honor limit when separator is empty
(issue 929).
Added missing failure check after expecting an identifier in
preparser (Chromium issue 62639).
Review URL: http://codereview.chromium.org/5188006
git-svn-id: http://v8.googlecode.com/svn/trunk@5853 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index bf27d0c..c50f84a 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -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