summaryrefslogtreecommitdiff
path: root/deps/v8/src/mips/full-codegen-mips.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/mips/full-codegen-mips.cc')
-rw-r--r--deps/v8/src/mips/full-codegen-mips.cc709
1 files changed, 358 insertions, 351 deletions
diff --git a/deps/v8/src/mips/full-codegen-mips.cc b/deps/v8/src/mips/full-codegen-mips.cc
index ff280ce76..639f57fd6 100644
--- a/deps/v8/src/mips/full-codegen-mips.cc
+++ b/deps/v8/src/mips/full-codegen-mips.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "v8.h"
+#include "src/v8.h"
#if V8_TARGET_ARCH_MIPS
@@ -14,18 +14,18 @@
// places where we have to move a previous result in v0 to a0 for the
// next call: mov(a0, v0). This is not needed on the other architectures.
-#include "code-stubs.h"
-#include "codegen.h"
-#include "compiler.h"
-#include "debug.h"
-#include "full-codegen.h"
-#include "isolate-inl.h"
-#include "parser.h"
-#include "scopes.h"
-#include "stub-cache.h"
+#include "src/code-stubs.h"
+#include "src/codegen.h"
+#include "src/compiler.h"
+#include "src/debug.h"
+#include "src/full-codegen.h"
+#include "src/isolate-inl.h"
+#include "src/parser.h"
+#include "src/scopes.h"
+#include "src/stub-cache.h"
-#include "mips/code-stubs-mips.h"
-#include "mips/macro-assembler-mips.h"
+#include "src/mips/code-stubs-mips.h"
+#include "src/mips/macro-assembler-mips.h"
namespace v8 {
namespace internal {
@@ -50,13 +50,13 @@ class JumpPatchSite BASE_EMBEDDED {
}
~JumpPatchSite() {
- ASSERT(patch_site_.is_bound() == info_emitted_);
+ DCHECK(patch_site_.is_bound() == info_emitted_);
}
// When initially emitting this ensure that a jump is always generated to skip
// the inlined smi code.
void EmitJumpIfNotSmi(Register reg, Label* target) {
- ASSERT(!patch_site_.is_bound() && !info_emitted_);
+ DCHECK(!patch_site_.is_bound() && !info_emitted_);
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
__ bind(&patch_site_);
__ andi(at, reg, 0);
@@ -68,7 +68,7 @@ class JumpPatchSite BASE_EMBEDDED {
// the inlined smi code.
void EmitJumpIfSmi(Register reg, Label* target) {
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
- ASSERT(!patch_site_.is_bound() && !info_emitted_);
+ DCHECK(!patch_site_.is_bound() && !info_emitted_);
__ bind(&patch_site_);
__ andi(at, reg, 0);
// Never taken before patched.
@@ -97,28 +97,6 @@ class JumpPatchSite BASE_EMBEDDED {
};
-static void EmitStackCheck(MacroAssembler* masm_,
- Register stack_limit_scratch,
- int pointers = 0,
- Register scratch = sp) {
- Isolate* isolate = masm_->isolate();
- Label ok;
- ASSERT(scratch.is(sp) == (pointers == 0));
- Heap::RootListIndex index;
- if (pointers != 0) {
- __ Subu(scratch, sp, Operand(pointers * kPointerSize));
- index = Heap::kRealStackLimitRootIndex;
- } else {
- index = Heap::kStackLimitRootIndex;
- }
- __ LoadRoot(stack_limit_scratch, index);
- __ Branch(&ok, hs, scratch, Operand(stack_limit_scratch));
- PredictableCodeSizeScope predictable(masm_, 4 * Assembler::kInstrSize);
- __ Call(isolate->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
- __ bind(&ok);
-}
-
-
// Generate code for a JS function. On entry to the function the receiver
// and arguments have been pushed on the stack left to right. The actual
// argument count matches the formal parameter count expected by the
@@ -163,7 +141,7 @@ void FullCodeGenerator::Generate() {
__ Branch(&ok, ne, a2, Operand(at));
__ lw(a2, GlobalObjectOperand());
- __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
+ __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalProxyOffset));
__ sw(a2, MemOperand(sp, receiver_offset));
@@ -176,16 +154,21 @@ void FullCodeGenerator::Generate() {
FrameScope frame_scope(masm_, StackFrame::MANUAL);
info->set_prologue_offset(masm_->pc_offset());
- __ Prologue(BUILD_FUNCTION_FRAME);
+ __ Prologue(info->IsCodePreAgingActive());
info->AddNoFrameRange(0, masm_->pc_offset());
{ Comment cmnt(masm_, "[ Allocate locals");
int locals_count = info->scope()->num_stack_slots();
// Generators allocate locals, if any, in context slots.
- ASSERT(!info->function()->is_generator() || locals_count == 0);
+ DCHECK(!info->function()->is_generator() || locals_count == 0);
if (locals_count > 0) {
if (locals_count >= 128) {
- EmitStackCheck(masm_, a2, locals_count, t5);
+ Label ok;
+ __ Subu(t5, sp, Operand(locals_count * kPointerSize));
+ __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
+ __ Branch(&ok, hs, t5, Operand(a2));
+ __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
+ __ bind(&ok);
}
__ LoadRoot(t5, Heap::kUndefinedValueRootIndex);
int kMaxPushes = FLAG_optimize_for_size ? 4 : 32;
@@ -219,16 +202,19 @@ void FullCodeGenerator::Generate() {
if (heap_slots > 0) {
Comment cmnt(masm_, "[ Allocate context");
// Argument to NewContext is the function, which is still in a1.
+ bool need_write_barrier = true;
if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
__ push(a1);
__ Push(info->scope()->GetScopeInfo());
- __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2);
+ __ CallRuntime(Runtime::kNewGlobalContext, 2);
} else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
FastNewContextStub stub(isolate(), heap_slots);
__ CallStub(&stub);
+ // Result of FastNewContextStub is always in new space.
+ need_write_barrier = false;
} else {
__ push(a1);
- __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1);
+ __ CallRuntime(Runtime::kNewFunctionContext, 1);
}
function_in_register = false;
// Context is returned in v0. It replaces the context passed to us.
@@ -249,8 +235,15 @@ void FullCodeGenerator::Generate() {
__ sw(a0, target);
// Update the write barrier.
- __ RecordWriteContextSlot(
- cp, target.offset(), a0, a3, kRAHasBeenSaved, kDontSaveFPRegs);
+ if (need_write_barrier) {
+ __ RecordWriteContextSlot(
+ cp, target.offset(), a0, a3, kRAHasBeenSaved, kDontSaveFPRegs);
+ } else if (FLAG_debug_code) {
+ Label done;
+ __ JumpIfInNewSpace(cp, a0, &done);
+ __ Abort(kExpectedNewSpaceObject);
+ __ bind(&done);
+ }
}
}
}
@@ -308,9 +301,9 @@ void FullCodeGenerator::Generate() {
// constant.
if (scope()->is_function_scope() && scope()->function() != NULL) {
VariableDeclaration* function = scope()->function();
- ASSERT(function->proxy()->var()->mode() == CONST ||
+ DCHECK(function->proxy()->var()->mode() == CONST ||
function->proxy()->var()->mode() == CONST_LEGACY);
- ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED);
+ DCHECK(function->proxy()->var()->location() != Variable::UNALLOCATED);
VisitVariableDeclaration(function);
}
VisitDeclarations(scope()->declarations());
@@ -318,13 +311,20 @@ void FullCodeGenerator::Generate() {
{ Comment cmnt(masm_, "[ Stack check");
PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
- EmitStackCheck(masm_, at);
+ Label ok;
+ __ LoadRoot(at, Heap::kStackLimitRootIndex);
+ __ Branch(&ok, hs, sp, Operand(at));
+ Handle<Code> stack_check = isolate()->builtins()->StackCheck();
+ PredictableCodeSizeScope predictable(masm_,
+ masm_->CallSize(stack_check, RelocInfo::CODE_TARGET));
+ __ Call(stack_check, RelocInfo::CODE_TARGET);
+ __ bind(&ok);
}
{ Comment cmnt(masm_, "[ Body");
- ASSERT(loop_depth() == 0);
+ DCHECK(loop_depth() == 0);
VisitStatements(function()->body());
- ASSERT(loop_depth() == 0);
+ DCHECK(loop_depth() == 0);
}
}
@@ -338,7 +338,7 @@ void FullCodeGenerator::Generate() {
void FullCodeGenerator::ClearAccumulator() {
- ASSERT(Smi::FromInt(0) == 0);
+ DCHECK(Smi::FromInt(0) == 0);
__ mov(v0, zero_reg);
}
@@ -353,7 +353,7 @@ void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
void FullCodeGenerator::EmitProfilingCounterReset() {
int reset_value = FLAG_interrupt_budget;
- if (isolate()->IsDebuggerActive()) {
+ if (info_->is_debug()) {
// Detect debug break requests as soon as possible.
reset_value = FLAG_interrupt_budget >> 4;
}
@@ -373,7 +373,7 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
Comment cmnt(masm_, "[ Back edge bookkeeping");
Label ok;
- ASSERT(back_edge_target->is_bound());
+ DCHECK(back_edge_target->is_bound());
int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
int weight = Min(kMaxBackEdgeWeight,
Max(1, distance / kCodeSizeMultiplier));
@@ -452,7 +452,7 @@ void FullCodeGenerator::EmitReturnSequence() {
#ifdef DEBUG
// Check that the size of the code used for returning is large enough
// for the debugger's requirements.
- ASSERT(Assembler::kJSReturnSequenceInstructions <=
+ DCHECK(Assembler::kJSReturnSequenceInstructions <=
masm_->InstructionsGeneratedSince(&check_exit_codesize));
#endif
}
@@ -460,18 +460,18 @@ void FullCodeGenerator::EmitReturnSequence() {
void FullCodeGenerator::EffectContext::Plug(Variable* var) const {
- ASSERT(var->IsStackAllocated() || var->IsContextSlot());
+ DCHECK(var->IsStackAllocated() || var->IsContextSlot());
}
void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const {
- ASSERT(var->IsStackAllocated() || var->IsContextSlot());
+ DCHECK(var->IsStackAllocated() || var->IsContextSlot());
codegen()->GetVar(result_register(), var);
}
void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
- ASSERT(var->IsStackAllocated() || var->IsContextSlot());
+ DCHECK(var->IsStackAllocated() || var->IsContextSlot());
codegen()->GetVar(result_register(), var);
__ push(result_register());
}
@@ -542,7 +542,7 @@ void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
true,
true_label_,
false_label_);
- ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals.
+ DCHECK(!lit->IsUndetectableObject()); // There are no undetectable literals.
if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
if (false_label_ != fall_through_) __ Branch(false_label_);
} else if (lit->IsTrue() || lit->IsJSObject()) {
@@ -569,7 +569,7 @@ void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
void FullCodeGenerator::EffectContext::DropAndPlug(int count,
Register reg) const {
- ASSERT(count > 0);
+ DCHECK(count > 0);
__ Drop(count);
}
@@ -577,7 +577,7 @@ void FullCodeGenerator::EffectContext::DropAndPlug(int count,
void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
int count,
Register reg) const {
- ASSERT(count > 0);
+ DCHECK(count > 0);
__ Drop(count);
__ Move(result_register(), reg);
}
@@ -585,7 +585,7 @@ void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
Register reg) const {
- ASSERT(count > 0);
+ DCHECK(count > 0);
if (count > 1) __ Drop(count - 1);
__ sw(reg, MemOperand(sp, 0));
}
@@ -593,7 +593,7 @@ void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
void FullCodeGenerator::TestContext::DropAndPlug(int count,
Register reg) const {
- ASSERT(count > 0);
+ DCHECK(count > 0);
// For simplicity we always test the accumulator register.
__ Drop(count);
__ Move(result_register(), reg);
@@ -604,7 +604,7 @@ void FullCodeGenerator::TestContext::DropAndPlug(int count,
void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
Label* materialize_false) const {
- ASSERT(materialize_true == materialize_false);
+ DCHECK(materialize_true == materialize_false);
__ bind(materialize_true);
}
@@ -640,8 +640,8 @@ void FullCodeGenerator::StackValueContext::Plug(
void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
Label* materialize_false) const {
- ASSERT(materialize_true == true_label_);
- ASSERT(materialize_false == false_label_);
+ DCHECK(materialize_true == true_label_);
+ DCHECK(materialize_false == false_label_);
}
@@ -707,7 +707,7 @@ void FullCodeGenerator::Split(Condition cc,
MemOperand FullCodeGenerator::StackOperand(Variable* var) {
- ASSERT(var->IsStackAllocated());
+ DCHECK(var->IsStackAllocated());
// Offset is negative because higher indexes are at lower addresses.
int offset = -var->index() * kPointerSize;
// Adjust by a (parameter or local) base offset.
@@ -721,7 +721,7 @@ MemOperand FullCodeGenerator::StackOperand(Variable* var) {
MemOperand FullCodeGenerator::VarOperand(Variable* var, Register scratch) {
- ASSERT(var->IsContextSlot() || var->IsStackAllocated());
+ DCHECK(var->IsContextSlot() || var->IsStackAllocated());
if (var->IsContextSlot()) {
int context_chain_length = scope()->ContextChainLength(var->scope());
__ LoadContext(scratch, context_chain_length);
@@ -743,10 +743,10 @@ void FullCodeGenerator::SetVar(Variable* var,
Register src,
Register scratch0,
Register scratch1) {
- ASSERT(var->IsContextSlot() || var->IsStackAllocated());
- ASSERT(!scratch0.is(src));
- ASSERT(!scratch0.is(scratch1));
- ASSERT(!scratch1.is(src));
+ DCHECK(var->IsContextSlot() || var->IsStackAllocated());
+ DCHECK(!scratch0.is(src));
+ DCHECK(!scratch0.is(scratch1));
+ DCHECK(!scratch1.is(src));
MemOperand location = VarOperand(var, scratch0);
__ sw(src, location);
// Emit the write barrier code if the location is in the heap.
@@ -784,7 +784,7 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr,
void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
// The variable in the declaration always resides in the current function
// context.
- ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
+ DCHECK_EQ(0, scope()->ContextChainLength(variable->scope()));
if (generate_debug_code_) {
// Check that we're not inside a with or catch context.
__ lw(a1, FieldMemOperand(cp, HeapObject::kMapOffset));
@@ -840,7 +840,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
Comment cmnt(masm_, "[ VariableDeclaration");
__ li(a2, Operand(variable->name()));
// Declaration nodes are always introduced in one of four modes.
- ASSERT(IsDeclaredVariableMode(mode));
+ DCHECK(IsDeclaredVariableMode(mode));
PropertyAttributes attr =
IsImmutableVariableMode(mode) ? READ_ONLY : NONE;
__ li(a1, Operand(Smi::FromInt(attr)));
@@ -852,11 +852,11 @@ void FullCodeGenerator::VisitVariableDeclaration(
__ LoadRoot(a0, Heap::kTheHoleValueRootIndex);
__ Push(cp, a2, a1, a0);
} else {
- ASSERT(Smi::FromInt(0) == 0);
+ DCHECK(Smi::FromInt(0) == 0);
__ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value.
__ Push(cp, a2, a1, a0);
}
- __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4);
+ __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
break;
}
}
@@ -871,7 +871,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
case Variable::UNALLOCATED: {
globals_->Add(variable->name(), zone());
Handle<SharedFunctionInfo> function =
- Compiler::BuildFunctionInfo(declaration->fun(), script());
+ Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow();
globals_->Add(function, zone());
@@ -912,7 +912,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
__ Push(cp, a2, a1);
// Push initial value for function declaration.
VisitForStackValue(declaration->fun());
- __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4);
+ __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
break;
}
}
@@ -921,8 +921,8 @@ void FullCodeGenerator::VisitFunctionDeclaration(
void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
Variable* variable = declaration->proxy()->var();
- ASSERT(variable->location() == Variable::CONTEXT);
- ASSERT(variable->interface()->IsFrozen());
+ DCHECK(variable->location() == Variable::CONTEXT);
+ DCHECK(variable->interface()->IsFrozen());
Comment cmnt(masm_, "[ ModuleDeclaration");
EmitDebugCheckDeclarationContext(variable);
@@ -984,7 +984,7 @@ void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
__ li(a1, Operand(pairs));
__ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
__ Push(cp, a1, a0);
- __ CallRuntime(Runtime::kHiddenDeclareGlobals, 3);
+ __ CallRuntime(Runtime::kDeclareGlobals, 3);
// Return value is ignored.
}
@@ -992,7 +992,7 @@ void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) {
// Call the runtime to declare the modules.
__ Push(descriptions);
- __ CallRuntime(Runtime::kHiddenDeclareModules, 1);
+ __ CallRuntime(Runtime::kDeclareModules, 1);
// Return value is ignored.
}
@@ -1221,7 +1221,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// For proxies, no filtering is done.
// TODO(rossberg): What if only a prototype is a proxy? Not specified yet.
- ASSERT_EQ(Smi::FromInt(0), 0);
+ DCHECK_EQ(Smi::FromInt(0), 0);
__ Branch(&update_each, eq, a2, Operand(zero_reg));
// Convert the entry to a string or (smi) 0 if it isn't a property
@@ -1272,27 +1272,8 @@ void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
Iteration loop_statement(this, stmt);
increment_loop_depth();
- // var iterator = iterable[@@iterator]()
- VisitForAccumulatorValue(stmt->assign_iterator());
- __ mov(a0, v0);
-
- // As with for-in, skip the loop if the iterator is null or undefined.
- __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
- __ Branch(loop_statement.break_label(), eq, a0, Operand(at));
- __ LoadRoot(at, Heap::kNullValueRootIndex);
- __ Branch(loop_statement.break_label(), eq, a0, Operand(at));
-
- // Convert the iterator to a JS object.
- Label convert, done_convert;
- __ JumpIfSmi(a0, &convert);
- __ GetObjectType(a0, a1, a1);
- __ Branch(&done_convert, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
- __ bind(&convert);
- __ push(a0);
- __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
- __ mov(a0, v0);
- __ bind(&done_convert);
- __ push(a0);
+ // var iterator = iterable[Symbol.iterator]();
+ VisitForEffect(stmt->assign_iterator());
// Loop entry.
__ bind(loop_statement.continue_label());
@@ -1349,7 +1330,7 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
__ LoadRoot(a1, pretenure ? Heap::kTrueValueRootIndex
: Heap::kFalseValueRootIndex);
__ Push(cp, a0, a1);
- __ CallRuntime(Runtime::kHiddenNewClosure, 3);
+ __ CallRuntime(Runtime::kNewClosure, 3);
}
context()->Plug(v0);
}
@@ -1361,7 +1342,7 @@ void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
}
-void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
+void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
TypeofState typeof_state,
Label* slow) {
Register current = cp;
@@ -1406,8 +1387,13 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
__ bind(&fast);
}
- __ lw(a0, GlobalObjectOperand());
- __ li(a2, Operand(var->name()));
+ __ lw(LoadIC::ReceiverRegister(), GlobalObjectOperand());
+ __ li(LoadIC::NameRegister(), Operand(proxy->var()->name()));
+ if (FLAG_vector_ics) {
+ __ li(LoadIC::SlotRegister(),
+ Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
+ }
+
ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
? NOT_CONTEXTUAL
: CONTEXTUAL;
@@ -1417,7 +1403,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
Label* slow) {
- ASSERT(var->IsContextSlot());
+ DCHECK(var->IsContextSlot());
Register context = cp;
Register next = a3;
Register temp = t0;
@@ -1445,7 +1431,7 @@ MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
}
-void FullCodeGenerator::EmitDynamicLookupFastCase(Variable* var,
+void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
TypeofState typeof_state,
Label* slow,
Label* done) {
@@ -1454,8 +1440,9 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(Variable* var,
// introducing variables. In those cases, we do not want to
// perform a runtime call for all variables in the scope
// containing the eval.
+ Variable* var = proxy->var();
if (var->mode() == DYNAMIC_GLOBAL) {
- EmitLoadGlobalCheckExtensions(var, typeof_state, slow);
+ EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
__ Branch(done);
} else if (var->mode() == DYNAMIC_LOCAL) {
Variable* local = var->local_if_not_shadowed();
@@ -1471,7 +1458,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(Variable* var,
__ Branch(done, ne, at, Operand(zero_reg));
__ li(a0, Operand(var->name()));
__ push(a0);
- __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1);
+ __ CallRuntime(Runtime::kThrowReferenceError, 1);
}
}
__ Branch(done);
@@ -1489,10 +1476,12 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
switch (var->location()) {
case Variable::UNALLOCATED: {
Comment cmnt(masm_, "[ Global variable");
- // Use inline caching. Variable name is passed in a2 and the global
- // object (receiver) in a0.
- __ lw(a0, GlobalObjectOperand());
- __ li(a2, Operand(var->name()));
+ __ lw(LoadIC::ReceiverRegister(), GlobalObjectOperand());
+ __ li(LoadIC::NameRegister(), Operand(var->name()));
+ if (FLAG_vector_ics) {
+ __ li(LoadIC::SlotRegister(),
+ Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
+ }
CallLoadIC(CONTEXTUAL);
context()->Plug(v0);
break;
@@ -1509,7 +1498,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
// always looked up dynamically, i.e. in that case
// var->location() == LOOKUP.
// always holds.
- ASSERT(var->scope() != NULL);
+ DCHECK(var->scope() != NULL);
// Check if the binding really needs an initialization check. The check
// can be skipped in the following situation: we have a LET or CONST
@@ -1532,8 +1521,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
skip_init_check = false;
} else {
// Check that we always have valid source position.
- ASSERT(var->initializer_position() != RelocInfo::kNoPosition);
- ASSERT(proxy->position() != RelocInfo::kNoPosition);
+ DCHECK(var->initializer_position() != RelocInfo::kNoPosition);
+ DCHECK(proxy->position() != RelocInfo::kNoPosition);
skip_init_check = var->mode() != CONST_LEGACY &&
var->initializer_position() < proxy->position();
}
@@ -1550,11 +1539,11 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
__ Branch(&done, ne, at, Operand(zero_reg));
__ li(a0, Operand(var->name()));
__ push(a0);
- __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1);
+ __ CallRuntime(Runtime::kThrowReferenceError, 1);
__ bind(&done);
} else {
// Uninitalized const bindings outside of harmony mode are unholed.
- ASSERT(var->mode() == CONST_LEGACY);
+ DCHECK(var->mode() == CONST_LEGACY);
__ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
__ Movz(v0, a0, at); // Conditional move: Undefined if TheHole.
}
@@ -1571,11 +1560,11 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
Label done, slow;
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
- EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done);
+ EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done);
__ bind(&slow);
__ li(a1, Operand(var->name()));
__ Push(cp, a1); // Context and name.
- __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2);
+ __ CallRuntime(Runtime::kLoadLookupSlot, 2);
__ bind(&done);
context()->Plug(v0);
}
@@ -1607,7 +1596,7 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
__ li(a2, Operand(expr->pattern()));
__ li(a1, Operand(expr->flags()));
__ Push(t0, a3, a2, a1);
- __ CallRuntime(Runtime::kHiddenMaterializeRegExpLiteral, 4);
+ __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
__ mov(t1, v0);
__ bind(&materialized);
@@ -1619,7 +1608,7 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
__ bind(&runtime_allocate);
__ li(a0, Operand(Smi::FromInt(size)));
__ Push(t1, a0);
- __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1);
+ __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
__ pop(t1);
__ bind(&allocated);
@@ -1661,10 +1650,10 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
__ li(a0, Operand(Smi::FromInt(flags)));
int properties_count = constant_properties->length() / 2;
if (expr->may_store_doubles() || expr->depth() > 1 ||
- Serializer::enabled(isolate()) || flags != ObjectLiteral::kFastElements ||
+ masm()->serializer_enabled() || flags != ObjectLiteral::kFastElements ||
properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
__ Push(a3, a2, a1, a0);
- __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4);
+ __ CallRuntime(Runtime::kCreateObjectLiteral, 4);
} else {
FastCloneShallowObjectStub stub(isolate(), properties_count);
__ CallStub(&stub);
@@ -1694,15 +1683,16 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::CONSTANT:
UNREACHABLE();
case ObjectLiteral::Property::MATERIALIZED_LITERAL:
- ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value()));
+ DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
// Fall through.
case ObjectLiteral::Property::COMPUTED:
if (key->value()->IsInternalizedString()) {
if (property->emit_store()) {
VisitForAccumulatorValue(value);
- __ mov(a0, result_register());
- __ li(a2, Operand(key->value()));
- __ lw(a1, MemOperand(sp));
+ __ mov(StoreIC::ValueRegister(), result_register());
+ DCHECK(StoreIC::ValueRegister().is(a0));
+ __ li(StoreIC::NameRegister(), Operand(key->value()));
+ __ lw(StoreIC::ReceiverRegister(), MemOperand(sp));
CallStoreIC(key->LiteralFeedbackId());
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
@@ -1716,7 +1706,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(key);
VisitForStackValue(value);
if (property->emit_store()) {
- __ li(a0, Operand(Smi::FromInt(NONE))); // PropertyAttributes.
+ __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes.
__ push(a0);
__ CallRuntime(Runtime::kSetProperty, 4);
} else {
@@ -1755,11 +1745,11 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
EmitAccessor(it->second->setter);
__ li(a0, Operand(Smi::FromInt(NONE)));
__ push(a0);
- __ CallRuntime(Runtime::kDefineOrRedefineAccessorProperty, 5);
+ __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
}
if (expr->has_function()) {
- ASSERT(result_saved);
+ DCHECK(result_saved);
__ lw(a0, MemOperand(sp));
__ push(a0);
__ CallRuntime(Runtime::kToFastProperties, 1);
@@ -1785,7 +1775,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
int length = subexprs->length();
Handle<FixedArray> constant_elements = expr->constant_elements();
- ASSERT_EQ(2, constant_elements->length());
+ DCHECK_EQ(2, constant_elements->length());
ElementsKind constant_elements_kind =
static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value());
bool has_fast_elements =
@@ -1805,33 +1795,12 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
__ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset));
__ li(a2, Operand(Smi::FromInt(expr->literal_index())));
__ li(a1, Operand(constant_elements));
- if (has_fast_elements && constant_elements_values->map() ==
- isolate()->heap()->fixed_cow_array_map()) {
- FastCloneShallowArrayStub stub(
- isolate(),
- FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
- allocation_site_mode,
- length);
- __ CallStub(&stub);
- __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(),
- 1, a1, a2);
- } else if (expr->depth() > 1 || Serializer::enabled(isolate()) ||
- length > FastCloneShallowArrayStub::kMaximumClonedLength) {
+ if (expr->depth() > 1 || length > JSObject::kInitialMaxFastElementArray) {
__ li(a0, Operand(Smi::FromInt(flags)));
__ Push(a3, a2, a1, a0);
- __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4);
+ __ CallRuntime(Runtime::kCreateArrayLiteral, 4);
} else {
- ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
- FLAG_smi_only_arrays);
- FastCloneShallowArrayStub::Mode mode =
- FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
-
- if (has_fast_elements) {
- mode = FastCloneShallowArrayStub::CLONE_ELEMENTS;
- }
-
- FastCloneShallowArrayStub stub(isolate(), mode, allocation_site_mode,
- length);
+ FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
__ CallStub(&stub);
}
@@ -1881,7 +1850,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
void FullCodeGenerator::VisitAssignment(Assignment* expr) {
- ASSERT(expr->target()->IsValidReferenceExpression());
+ DCHECK(expr->target()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ Assignment");
@@ -1903,9 +1872,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
break;
case NAMED_PROPERTY:
if (expr->is_compound()) {
- // We need the receiver both on the stack and in the accumulator.
- VisitForAccumulatorValue(property->obj());
- __ push(result_register());
+ // We need the receiver both on the stack and in the register.
+ VisitForStackValue(property->obj());
+ __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
} else {
VisitForStackValue(property->obj());
}
@@ -1914,9 +1883,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
// We need the key and receiver on both the stack and in v0 and a1.
if (expr->is_compound()) {
VisitForStackValue(property->obj());
- VisitForAccumulatorValue(property->key());
- __ lw(a1, MemOperand(sp, 0));
- __ push(v0);
+ VisitForStackValue(property->key());
+ __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 1 * kPointerSize));
+ __ lw(LoadIC::NameRegister(), MemOperand(sp, 0));
} else {
VisitForStackValue(property->obj());
VisitForStackValue(property->key());
@@ -2012,7 +1981,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ bind(&suspend);
VisitForAccumulatorValue(expr->generator_object());
- ASSERT(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
+ DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
__ li(a1, Operand(Smi::FromInt(continuation.pos())));
__ sw(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset));
__ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset));
@@ -2022,7 +1991,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset));
__ Branch(&post_runtime, eq, sp, Operand(a1));
__ push(v0); // generator object
- __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1);
+ __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
__ bind(&post_runtime);
__ pop(result_register());
@@ -2053,7 +2022,10 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// [sp + 0 * kPointerSize] g
Label l_catch, l_try, l_suspend, l_continuation, l_resume;
- Label l_next, l_call, l_loop;
+ Label l_next, l_call;
+ Register load_receiver = LoadIC::ReceiverRegister();
+ Register load_name = LoadIC::NameRegister();
+
// Initial send value is undefined.
__ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
__ Branch(&l_next);
@@ -2062,9 +2034,9 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ bind(&l_catch);
__ mov(a0, v0);
handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
- __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw"
- __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
- __ Push(a2, a3, a0); // "throw", iter, except
+ __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw"
+ __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
+ __ Push(load_name, a3, a0); // "throw", iter, except
__ jmp(&l_call);
// try { received = %yield result }
@@ -2083,14 +2055,14 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
const int generator_object_depth = kPointerSize + handler_size;
__ lw(a0, MemOperand(sp, generator_object_depth));
__ push(a0); // g
- ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
+ DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
__ li(a1, Operand(Smi::FromInt(l_continuation.pos())));
__ sw(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset));
__ sw(cp, FieldMemOperand(a0, JSGeneratorObject::kContextOffset));
__ mov(a1, cp);
__ RecordWriteField(a0, JSGeneratorObject::kContextOffset, a1, a2,
kRAHasBeenSaved, kDontSaveFPRegs);
- __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1);
+ __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
__ pop(v0); // result
EmitReturnSequence();
@@ -2100,14 +2072,19 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// receiver = iter; f = 'next'; arg = received;
__ bind(&l_next);
- __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next"
- __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
- __ Push(a2, a3, a0); // "next", iter, received
+
+ __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next"
+ __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
+ __ Push(load_name, a3, a0); // "next", iter, received
// result = receiver[f](arg);
__ bind(&l_call);
- __ lw(a1, MemOperand(sp, kPointerSize));
- __ lw(a0, MemOperand(sp, 2 * kPointerSize));
+ __ lw(load_receiver, MemOperand(sp, kPointerSize));
+ __ lw(load_name, MemOperand(sp, 2 * kPointerSize));
+ if (FLAG_vector_ics) {
+ __ li(LoadIC::SlotRegister(),
+ Operand(Smi::FromInt(expr->KeyedLoadFeedbackSlot())));
+ }
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallIC(ic, TypeFeedbackId::None());
__ mov(a0, v0);
@@ -2120,21 +2097,29 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ Drop(1); // The function is still on the stack; drop it.
// if (!result.done) goto l_try;
- __ bind(&l_loop);
- __ mov(a0, v0);
- __ push(a0); // save result
- __ LoadRoot(a2, Heap::kdone_stringRootIndex); // "done"
- CallLoadIC(NOT_CONTEXTUAL); // result.done in v0
+ __ Move(load_receiver, v0);
+
+ __ push(load_receiver); // save result
+ __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
+ if (FLAG_vector_ics) {
+ __ li(LoadIC::SlotRegister(),
+ Operand(Smi::FromInt(expr->DoneFeedbackSlot())));
+ }
+ CallLoadIC(NOT_CONTEXTUAL); // v0=result.done
__ mov(a0, v0);
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic);
__ Branch(&l_try, eq, v0, Operand(zero_reg));
// result.value
- __ pop(a0); // result
- __ LoadRoot(a2, Heap::kvalue_stringRootIndex); // "value"
- CallLoadIC(NOT_CONTEXTUAL); // result.value in v0
- context()->DropAndPlug(2, v0); // drop iter and g
+ __ pop(load_receiver); // result
+ __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
+ if (FLAG_vector_ics) {
+ __ li(LoadIC::SlotRegister(),
+ Operand(Smi::FromInt(expr->ValueFeedbackSlot())));
+ }
+ CallLoadIC(NOT_CONTEXTUAL); // v0=result.value
+ context()->DropAndPlug(2, v0); // drop iter and g
break;
}
}
@@ -2145,7 +2130,7 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
Expression *value,
JSGeneratorObject::ResumeMode resume_mode) {
// The value stays in a0, and is ultimately read by the resumed generator, as
- // if CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject) returned it. Or it
+ // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
// is read to throw the value when the resumed generator is already closed.
// a1 will hold the generator object until the activation has been resumed.
VisitForStackValue(generator);
@@ -2224,10 +2209,10 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
__ push(a2);
__ Branch(&push_operand_holes);
__ bind(&call_resume);
- ASSERT(!result_register().is(a1));
+ DCHECK(!result_register().is(a1));
__ Push(a1, result_register());
__ Push(Smi::FromInt(resume_mode));
- __ CallRuntime(Runtime::kHiddenResumeJSGeneratorObject, 3);
+ __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
// Not reached: the runtime call returns elsewhere.
__ stop("not-reached");
@@ -2242,14 +2227,14 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
} else {
// Throw the provided value.
__ push(a0);
- __ CallRuntime(Runtime::kHiddenThrow, 1);
+ __ CallRuntime(Runtime::kThrow, 1);
}
__ jmp(&done);
// Throw error if we attempt to operate on a running generator.
__ bind(&wrong_state);
__ push(a1);
- __ CallRuntime(Runtime::kHiddenThrowGeneratorStateError, 1);
+ __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
__ bind(&done);
context()->Plug(result_register());
@@ -2267,7 +2252,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
__ bind(&gc_required);
__ Push(Smi::FromInt(map->instance_size()));
- __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1);
+ __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
__ lw(context_register(),
MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2276,7 +2261,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
__ pop(a2);
__ li(a3, Operand(isolate()->factory()->ToBoolean(done)));
__ li(t0, Operand(isolate()->factory()->empty_fixed_array()));
- ASSERT_EQ(map->instance_size(), 5 * kPointerSize);
+ DCHECK_EQ(map->instance_size(), 5 * kPointerSize);
__ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
__ sw(t0, FieldMemOperand(v0, JSObject::kPropertiesOffset));
__ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset));
@@ -2295,19 +2280,27 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
- __ mov(a0, result_register());
- __ li(a2, Operand(key->value()));
- // Call load IC. It has arguments receiver and property name a0 and a2.
- CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
+ __ li(LoadIC::NameRegister(), Operand(key->value()));
+ if (FLAG_vector_ics) {
+ __ li(LoadIC::SlotRegister(),
+ Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
+ CallLoadIC(NOT_CONTEXTUAL);
+ } else {
+ CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
+ }
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
- __ mov(a0, result_register());
- // Call keyed load IC. It has arguments key and receiver in a0 and a1.
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
- CallIC(ic, prop->PropertyFeedbackId());
+ if (FLAG_vector_ics) {
+ __ li(LoadIC::SlotRegister(),
+ Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
+ CallIC(ic);
+ } else {
+ CallIC(ic, prop->PropertyFeedbackId());
+ }
}
@@ -2385,7 +2378,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ Branch(&done, ne, v0, Operand(zero_reg));
__ Addu(scratch2, right, left);
__ Branch(&stub_call, lt, scratch2, Operand(zero_reg));
- ASSERT(Smi::FromInt(0) == 0);
+ DCHECK(Smi::FromInt(0) == 0);
__ mov(v0, zero_reg);
break;
}
@@ -2421,7 +2414,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
void FullCodeGenerator::EmitAssignment(Expression* expr) {
- ASSERT(expr->IsValidReferenceExpression());
+ DCHECK(expr->IsValidReferenceExpression());
// Left-hand side can only be a property, a global or a (parameter or local)
// slot.
@@ -2444,9 +2437,10 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
case NAMED_PROPERTY: {
__ push(result_register()); // Preserve value.
VisitForAccumulatorValue(prop->obj());
- __ mov(a1, result_register());
- __ pop(a0); // Restore value.
- __ li(a2, Operand(prop->key()->AsLiteral()->value()));
+ __ mov(StoreIC::ReceiverRegister(), result_register());
+ __ pop(StoreIC::ValueRegister()); // Restore value.
+ __ li(StoreIC::NameRegister(),
+ Operand(prop->key()->AsLiteral()->value()));
CallStoreIC();
break;
}
@@ -2454,8 +2448,8 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
__ push(result_register()); // Preserve value.
VisitForStackValue(prop->obj());
VisitForAccumulatorValue(prop->key());
- __ mov(a1, result_register());
- __ Pop(a0, a2); // a0 = restored value.
+ __ mov(KeyedStoreIC::NameRegister(), result_register());
+ __ Pop(KeyedStoreIC::ValueRegister(), KeyedStoreIC::ReceiverRegister());
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
@@ -2480,32 +2474,23 @@ void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
}
-void FullCodeGenerator::EmitCallStoreContextSlot(
- Handle<String> name, StrictMode strict_mode) {
- __ li(a1, Operand(name));
- __ li(a0, Operand(Smi::FromInt(strict_mode)));
- __ Push(v0, cp, a1, a0); // Value, context, name, strict mode.
- __ CallRuntime(Runtime::kHiddenStoreContextSlot, 4);
-}
-
-
void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
if (var->IsUnallocated()) {
// Global var, const, or let.
- __ mov(a0, result_register());
- __ li(a2, Operand(var->name()));
- __ lw(a1, GlobalObjectOperand());
+ __ mov(StoreIC::ValueRegister(), result_register());
+ __ li(StoreIC::NameRegister(), Operand(var->name()));
+ __ lw(StoreIC::ReceiverRegister(), GlobalObjectOperand());
CallStoreIC();
} else if (op == Token::INIT_CONST_LEGACY) {
// Const initializers need a write barrier.
- ASSERT(!var->IsParameter()); // No const parameters.
+ DCHECK(!var->IsParameter()); // No const parameters.
if (var->IsLookupSlot()) {
__ li(a0, Operand(var->name()));
__ Push(v0, cp, a0); // Context and name.
- __ CallRuntime(Runtime::kHiddenInitializeConstContextSlot, 3);
+ __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
} else {
- ASSERT(var->IsStackAllocated() || var->IsContextSlot());
+ DCHECK(var->IsStackAllocated() || var->IsContextSlot());
Label skip;
MemOperand location = VarOperand(var, a1);
__ lw(a2, location);
@@ -2517,30 +2502,31 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
} else if (var->mode() == LET && op != Token::INIT_LET) {
// Non-initializing assignment to let variable needs a write barrier.
- if (var->IsLookupSlot()) {
- EmitCallStoreContextSlot(var->name(), strict_mode());
- } else {
- ASSERT(var->IsStackAllocated() || var->IsContextSlot());
- Label assign;
- MemOperand location = VarOperand(var, a1);
- __ lw(a3, location);
- __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
- __ Branch(&assign, ne, a3, Operand(t0));
- __ li(a3, Operand(var->name()));
- __ push(a3);
- __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1);
- // Perform the assignment.
- __ bind(&assign);
- EmitStoreToStackLocalOrContextSlot(var, location);
- }
+ DCHECK(!var->IsLookupSlot());
+ DCHECK(var->IsStackAllocated() || var->IsContextSlot());
+ Label assign;
+ MemOperand location = VarOperand(var, a1);
+ __ lw(a3, location);
+ __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
+ __ Branch(&assign, ne, a3, Operand(t0));
+ __ li(a3, Operand(var->name()));
+ __ push(a3);
+ __ CallRuntime(Runtime::kThrowReferenceError, 1);
+ // Perform the assignment.
+ __ bind(&assign);
+ EmitStoreToStackLocalOrContextSlot(var, location);
} else if (!var->is_const_mode() || op == Token::INIT_CONST) {
- // Assignment to var or initializing assignment to let/const
- // in harmony mode.
if (var->IsLookupSlot()) {
- EmitCallStoreContextSlot(var->name(), strict_mode());
+ // Assignment to var.
+ __ li(a1, Operand(var->name()));
+ __ li(a0, Operand(Smi::FromInt(strict_mode())));
+ __ Push(v0, cp, a1, a0); // Value, context, name, strict mode.
+ __ CallRuntime(Runtime::kStoreLookupSlot, 4);
} else {
- ASSERT((var->IsStackAllocated() || var->IsContextSlot()));
+ // Assignment to var or initializing assignment to let/const in harmony
+ // mode.
+ DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
MemOperand location = VarOperand(var, a1);
if (generate_debug_code_ && op == Token::INIT_LET) {
// Check for an uninitialized let binding.
@@ -2558,15 +2544,14 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a named store IC.
Property* prop = expr->target()->AsProperty();
- ASSERT(prop != NULL);
- ASSERT(prop->key()->AsLiteral() != NULL);
+ DCHECK(prop != NULL);
+ DCHECK(prop->key()->IsLiteral());
// Record source code position before IC call.
SetSourcePosition(expr->position());
- __ mov(a0, result_register()); // Load the value.
- __ li(a2, Operand(prop->key()->AsLiteral()->value()));
- __ pop(a1);
-
+ __ mov(StoreIC::ValueRegister(), result_register());
+ __ li(StoreIC::NameRegister(), Operand(prop->key()->AsLiteral()->value()));
+ __ pop(StoreIC::ReceiverRegister());
CallStoreIC(expr->AssignmentFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
@@ -2584,8 +2569,9 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// - a0 is the value,
// - a1 is the key,
// - a2 is the receiver.
- __ mov(a0, result_register());
- __ Pop(a2, a1); // a1 = key.
+ __ mov(KeyedStoreIC::ValueRegister(), result_register());
+ __ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::NameRegister());
+ DCHECK(KeyedStoreIC::ValueRegister().is(a0));
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
@@ -2603,13 +2589,15 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
if (key->IsPropertyName()) {
VisitForAccumulatorValue(expr->obj());
+ __ Move(LoadIC::ReceiverRegister(), v0);
EmitNamedPropertyLoad(expr);
PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(v0);
} else {
VisitForStackValue(expr->obj());
VisitForAccumulatorValue(expr->key());
- __ pop(a1);
+ __ Move(LoadIC::NameRegister(), v0);
+ __ pop(LoadIC::ReceiverRegister());
EmitKeyedPropertyLoad(expr);
context()->Plug(v0);
}
@@ -2642,8 +2630,8 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
__ Push(isolate()->factory()->undefined_value());
} else {
// Load the function from the receiver.
- ASSERT(callee->IsProperty());
- __ lw(v0, MemOperand(sp, 0));
+ DCHECK(callee->IsProperty());
+ __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
EmitNamedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
// Push the target function under the receiver.
@@ -2665,8 +2653,9 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
Expression* callee = expr->expression();
// Load the function from the receiver.
- ASSERT(callee->IsProperty());
- __ lw(a1, MemOperand(sp, 0));
+ DCHECK(callee->IsProperty());
+ __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
+ __ Move(LoadIC::NameRegister(), v0);
EmitKeyedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
@@ -2726,7 +2715,7 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
// Do the runtime call.
__ Push(t2, t1, t0, a1);
- __ CallRuntime(Runtime::kHiddenResolvePossiblyDirectEval, 5);
+ __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
}
@@ -2789,16 +2778,16 @@ void FullCodeGenerator::VisitCall(Call* expr) {
{ PreservePositionScope scope(masm()->positions_recorder());
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
- EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
+ EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done);
}
__ bind(&slow);
// Call the runtime to find the function to call (returned in v0)
// and the object holding it (returned in v1).
- ASSERT(!context_register().is(a2));
+ DCHECK(!context_register().is(a2));
__ li(a2, Operand(proxy->name()));
__ Push(context_register(), a2);
- __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2);
+ __ CallRuntime(Runtime::kLoadLookupSlot, 2);
__ Push(v0, v1); // Function, receiver.
// If fast case code has been generated, emit code to push the
@@ -2831,7 +2820,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
EmitKeyedCallWithLoadIC(expr, property->key());
}
} else {
- ASSERT(call_type == Call::OTHER_CALL);
+ DCHECK(call_type == Call::OTHER_CALL);
// Call to an arbitrary expression not handled specially above.
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(callee);
@@ -2844,7 +2833,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
#ifdef DEBUG
// RecordJSReturnSite should have been called.
- ASSERT(expr->return_is_recorded_);
+ DCHECK(expr->return_is_recorded_);
#endif
}
@@ -2878,7 +2867,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
// Record call targets in unoptimized code.
if (FLAG_pretenuring_call_new) {
EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
- ASSERT(expr->AllocationSiteFeedbackSlot() ==
+ DCHECK(expr->AllocationSiteFeedbackSlot() ==
expr->CallNewFeedbackSlot() + 1);
}
@@ -2894,7 +2883,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
@@ -2915,7 +2904,7 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
@@ -2936,7 +2925,7 @@ void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
void FullCodeGenerator::EmitIsObject(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
@@ -2967,7 +2956,7 @@ void FullCodeGenerator::EmitIsObject(CallRuntime* expr) {
void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
@@ -2990,7 +2979,7 @@ void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) {
void FullCodeGenerator::EmitIsUndetectableObject(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
@@ -3015,7 +3004,7 @@ void FullCodeGenerator::EmitIsUndetectableObject(CallRuntime* expr) {
void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
@@ -3060,7 +3049,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ Addu(t0, t0, Operand(DescriptorArray::kFirstOffset - kHeapObjectTag));
// Calculate the end of the descriptor array.
__ mov(a2, t0);
- __ sll(t1, a3, kPointerSizeLog2 - kSmiTagSize);
+ __ sll(t1, a3, kPointerSizeLog2);
__ Addu(a2, a2, t1);
// Loop through all the keys in the descriptor array. If one of these is the
@@ -3102,7 +3091,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
@@ -3125,7 +3114,7 @@ void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) {
void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
@@ -3155,7 +3144,7 @@ void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
@@ -3178,7 +3167,7 @@ void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
@@ -3199,7 +3188,7 @@ void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
- ASSERT(expr->arguments()->length() == 0);
+ DCHECK(expr->arguments()->length() == 0);
Label materialize_true, materialize_false;
Label* if_true = NULL;
@@ -3231,7 +3220,7 @@ void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 2);
+ DCHECK(args->length() == 2);
// Load the two objects into registers and perform the comparison.
VisitForStackValue(args->at(0));
@@ -3254,7 +3243,7 @@ void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
void FullCodeGenerator::EmitArguments(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
// ArgumentsAccessStub expects the key in a1 and the formal
// parameter count in a0.
@@ -3268,7 +3257,7 @@ void FullCodeGenerator::EmitArguments(CallRuntime* expr) {
void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) {
- ASSERT(expr->arguments()->length() == 0);
+ DCHECK(expr->arguments()->length() == 0);
Label exit;
// Get the number of formal parameters.
__ li(v0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
@@ -3290,7 +3279,7 @@ void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) {
void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
Label done, null, function, non_function_constructor;
VisitForAccumulatorValue(args->at(0));
@@ -3352,7 +3341,7 @@ void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
// Load the arguments on the stack and call the stub.
SubStringStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 3);
+ DCHECK(args->length() == 3);
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
VisitForStackValue(args->at(2));
@@ -3365,7 +3354,7 @@ void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) {
// Load the arguments on the stack and call the stub.
RegExpExecStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 4);
+ DCHECK(args->length() == 4);
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
VisitForStackValue(args->at(2));
@@ -3377,7 +3366,7 @@ void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) {
void FullCodeGenerator::EmitValueOf(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0)); // Load the object.
@@ -3397,8 +3386,8 @@ void FullCodeGenerator::EmitValueOf(CallRuntime* expr) {
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 2);
- ASSERT_NE(NULL, args->at(1)->AsLiteral());
+ DCHECK(args->length() == 2);
+ DCHECK_NE(NULL, args->at(1)->AsLiteral());
Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value()));
VisitForAccumulatorValue(args->at(0)); // Load the object.
@@ -3436,7 +3425,7 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
}
__ bind(&not_date_object);
- __ CallRuntime(Runtime::kHiddenThrowNotDateError, 0);
+ __ CallRuntime(Runtime::kThrowNotDateError, 0);
__ bind(&done);
context()->Plug(v0);
}
@@ -3444,7 +3433,7 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT_EQ(3, args->length());
+ DCHECK_EQ(3, args->length());
Register string = v0;
Register index = a1;
@@ -3481,7 +3470,7 @@ void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT_EQ(3, args->length());
+ DCHECK_EQ(3, args->length());
Register string = v0;
Register index = a1;
@@ -3519,7 +3508,7 @@ void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
// Load the arguments on the stack and call the runtime function.
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 2);
+ DCHECK(args->length() == 2);
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
MathPowStub stub(isolate(), MathPowStub::ON_STACK);
@@ -3530,7 +3519,7 @@ void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 2);
+ DCHECK(args->length() == 2);
VisitForStackValue(args->at(0)); // Load the object.
VisitForAccumulatorValue(args->at(1)); // Load the value.
@@ -3559,7 +3548,7 @@ void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) {
void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT_EQ(args->length(), 1);
+ DCHECK_EQ(args->length(), 1);
// Load the argument into a0 and call the stub.
VisitForAccumulatorValue(args->at(0));
@@ -3573,7 +3562,7 @@ void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
@@ -3592,7 +3581,7 @@ void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 2);
+ DCHECK(args->length() == 2);
VisitForStackValue(args->at(0));
VisitForAccumulatorValue(args->at(1));
@@ -3639,7 +3628,7 @@ void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) {
void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 2);
+ DCHECK(args->length() == 2);
VisitForStackValue(args->at(0));
VisitForAccumulatorValue(args->at(1));
@@ -3688,7 +3677,7 @@ void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT_EQ(2, args->length());
+ DCHECK_EQ(2, args->length());
VisitForStackValue(args->at(0));
VisitForAccumulatorValue(args->at(1));
@@ -3702,7 +3691,7 @@ void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) {
void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT_EQ(2, args->length());
+ DCHECK_EQ(2, args->length());
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
@@ -3715,7 +3704,7 @@ void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() >= 2);
+ DCHECK(args->length() >= 2);
int arg_count = args->length() - 2; // 2 ~ receiver and function.
for (int i = 0; i < arg_count + 1; i++) {
@@ -3748,7 +3737,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
RegExpConstructResultStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 3);
+ DCHECK(args->length() == 3);
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
VisitForAccumulatorValue(args->at(2));
@@ -3762,9 +3751,9 @@ void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT_EQ(2, args->length());
+ DCHECK_EQ(2, args->length());
- ASSERT_NE(NULL, args->at(0)->AsLiteral());
+ DCHECK_NE(NULL, args->at(0)->AsLiteral());
int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value();
Handle<FixedArray> jsfunction_result_caches(
@@ -3807,7 +3796,7 @@ void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
__ bind(&not_found);
// Call runtime to perform the lookup.
__ Push(cache, key);
- __ CallRuntime(Runtime::kHiddenGetFromCache, 2);
+ __ CallRuntime(Runtime::kGetFromCache, 2);
__ bind(&done);
context()->Plug(v0);
@@ -3837,7 +3826,7 @@ void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
+ DCHECK(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
__ AssertString(v0);
@@ -3855,7 +3844,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
empty_separator_loop, one_char_separator_loop,
one_char_separator_loop_entry, long_separator_loop;
ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 2);
+ DCHECK(args->length() == 2);
VisitForStackValue(args->at(1));
VisitForAccumulatorValue(args->at(0));
@@ -4016,7 +4005,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
__ CopyBytes(string, result_pos, string_length, scratch1);
// End while (element < elements_end).
__ Branch(&empty_separator_loop, lt, element, Operand(elements_end));
- ASSERT(result.is(v0));
+ DCHECK(result.is(v0));
__ Branch(&done);
// One-character separator case.
@@ -4048,7 +4037,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
__ CopyBytes(string, result_pos, string_length, scratch1);
// End while (element < elements_end).
__ Branch(&one_char_separator_loop, lt, element, Operand(elements_end));
- ASSERT(result.is(v0));
+ DCHECK(result.is(v0));
__ Branch(&done);
// Long separator case (separator is more than one character). Entry is at the
@@ -4077,7 +4066,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
__ CopyBytes(string, result_pos, string_length, scratch1);
// End while (element < elements_end).
__ Branch(&long_separator_loop, lt, element, Operand(elements_end));
- ASSERT(result.is(v0));
+ DCHECK(result.is(v0));
__ Branch(&done);
__ bind(&bailout);
@@ -4087,6 +4076,17 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
}
+void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
+ DCHECK(expr->arguments()->length() == 0);
+ ExternalReference debug_is_active =
+ ExternalReference::debug_is_active_address(isolate());
+ __ li(at, Operand(debug_is_active));
+ __ lb(v0, MemOperand(at));
+ __ SmiTag(v0);
+ context()->Plug(v0);
+}
+
+
void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
if (expr->function() != NULL &&
expr->function()->intrinsic_type == Runtime::INLINE) {
@@ -4101,12 +4101,20 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
if (expr->is_jsruntime()) {
// Push the builtins object as the receiver.
- __ lw(a0, GlobalObjectOperand());
- __ lw(a0, FieldMemOperand(a0, GlobalObject::kBuiltinsOffset));
- __ push(a0);
+ Register receiver = LoadIC::ReceiverRegister();
+ __ lw(receiver, GlobalObjectOperand());
+ __ lw(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset));
+ __ push(receiver);
+
// Load the function from the receiver.
- __ li(a2, Operand(expr->name()));
- CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
+ __ li(LoadIC::NameRegister(), Operand(expr->name()));
+ if (FLAG_vector_ics) {
+ __ li(LoadIC::SlotRegister(),
+ Operand(Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
+ CallLoadIC(NOT_CONTEXTUAL);
+ } else {
+ CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
+ }
// Push the target function under the receiver.
__ lw(at, MemOperand(sp, 0));
@@ -4160,7 +4168,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
Variable* var = proxy->var();
// Delete of an unqualified identifier is disallowed in strict mode
// but "delete this" is allowed.
- ASSERT(strict_mode() == SLOPPY || var->is_this());
+ DCHECK(strict_mode() == SLOPPY || var->is_this());
if (var->IsUnallocated()) {
__ lw(a2, GlobalObjectOperand());
__ li(a1, Operand(var->name()));
@@ -4175,10 +4183,10 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
} else {
// Non-global variable. Call the runtime to try to delete from the
// context where the variable was introduced.
- ASSERT(!context_register().is(a2));
+ DCHECK(!context_register().is(a2));
__ li(a2, Operand(var->name()));
__ Push(context_register(), a2);
- __ CallRuntime(Runtime::kHiddenDeleteContextSlot, 2);
+ __ CallRuntime(Runtime::kDeleteLookupSlot, 2);
context()->Plug(v0);
}
} else {
@@ -4216,7 +4224,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
// for control and plugging the control flow into the context,
// because we need to prepare a pair of extra administrative AST ids
// for the optimizing compiler.
- ASSERT(context()->IsAccumulatorValue() || context()->IsStackValue());
+ DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
Label materialize_true, materialize_false, done;
VisitForControl(expr->expression(),
&materialize_false,
@@ -4253,7 +4261,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
- ASSERT(expr->expression()->IsValidReferenceExpression());
+ DCHECK(expr->expression()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ CountOperation");
SetSourcePosition(expr->position());
@@ -4272,7 +4280,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
// Evaluate expression and get value.
if (assign_type == VARIABLE) {
- ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
+ DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
AccumulatorValueContext context(this);
EmitVariableLoad(expr->expression()->AsVariableProxy());
} else {
@@ -4282,15 +4290,15 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ push(at);
}
if (assign_type == NAMED_PROPERTY) {
- // Put the object both on the stack and in the accumulator.
- VisitForAccumulatorValue(prop->obj());
- __ push(v0);
+ // Put the object both on the stack and in the register.
+ VisitForStackValue(prop->obj());
+ __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
EmitNamedPropertyLoad(prop);
} else {
VisitForStackValue(prop->obj());
- VisitForAccumulatorValue(prop->key());
- __ lw(a1, MemOperand(sp, 0));
- __ push(v0);
+ VisitForStackValue(prop->key());
+ __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 1 * kPointerSize));
+ __ lw(LoadIC::NameRegister(), MemOperand(sp, 0));
EmitKeyedPropertyLoad(prop);
}
}
@@ -4401,9 +4409,10 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
break;
case NAMED_PROPERTY: {
- __ mov(a0, result_register()); // Value.
- __ li(a2, Operand(prop->key()->AsLiteral()->value())); // Name.
- __ pop(a1); // Receiver.
+ __ mov(StoreIC::ValueRegister(), result_register());
+ __ li(StoreIC::NameRegister(),
+ Operand(prop->key()->AsLiteral()->value()));
+ __ pop(StoreIC::ReceiverRegister());
CallStoreIC(expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
@@ -4416,8 +4425,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
break;
}
case KEYED_PROPERTY: {
- __ mov(a0, result_register()); // Value.
- __ Pop(a2, a1); // a1 = key, a2 = receiver.
+ __ mov(KeyedStoreIC::ValueRegister(), result_register());
+ __ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::NameRegister());
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
@@ -4437,13 +4446,17 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
- ASSERT(!context()->IsEffect());
- ASSERT(!context()->IsTest());
+ DCHECK(!context()->IsEffect());
+ DCHECK(!context()->IsTest());
VariableProxy* proxy = expr->AsVariableProxy();
if (proxy != NULL && proxy->var()->IsUnallocated()) {
Comment cmnt(masm_, "[ Global variable");
- __ lw(a0, GlobalObjectOperand());
- __ li(a2, Operand(proxy->name()));
+ __ lw(LoadIC::ReceiverRegister(), GlobalObjectOperand());
+ __ li(LoadIC::NameRegister(), Operand(proxy->name()));
+ if (FLAG_vector_ics) {
+ __ li(LoadIC::SlotRegister(),
+ Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
+ }
// Use a regular load, not a contextual load, to avoid a reference
// error.
CallLoadIC(NOT_CONTEXTUAL);
@@ -4455,12 +4468,12 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
- EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done);
+ EmitDynamicLookupFastCase(proxy, INSIDE_TYPEOF, &slow, &done);
__ bind(&slow);
__ li(a0, Operand(proxy->name()));
__ Push(cp, a0);
- __ CallRuntime(Runtime::kHiddenLoadContextSlotNoReferenceError, 2);
+ __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2);
PrepareForBailout(expr, TOS_REG);
__ bind(&done);
@@ -4510,10 +4523,6 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ Branch(if_true, eq, v0, Operand(at));
__ LoadRoot(at, Heap::kFalseValueRootIndex);
Split(eq, v0, Operand(at), if_true, if_false, fall_through);
- } else if (FLAG_harmony_typeof &&
- String::Equals(check, factory->null_string())) {
- __ LoadRoot(at, Heap::kNullValueRootIndex);
- Split(eq, v0, Operand(at), if_true, if_false, fall_through);
} else if (String::Equals(check, factory->undefined_string())) {
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
__ Branch(if_true, eq, v0, Operand(at));
@@ -4532,10 +4541,8 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
if_true, if_false, fall_through);
} else if (String::Equals(check, factory->object_string())) {
__ JumpIfSmi(v0, if_false);
- if (!FLAG_harmony_typeof) {
- __ LoadRoot(at, Heap::kNullValueRootIndex);
- __ Branch(if_true, eq, v0, Operand(at));
- }
+ __ LoadRoot(at, Heap::kNullValueRootIndex);
+ __ Branch(if_true, eq, v0, Operand(at));
// Check for JS objects => true.
__ GetObjectType(v0, v0, a1);
__ Branch(if_false, lt, a1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
@@ -4666,7 +4673,7 @@ Register FullCodeGenerator::context_register() {
void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
- ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
+ DCHECK_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
__ sw(value, MemOperand(fp, frame_offset));
}
@@ -4691,7 +4698,7 @@ void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
// code. Fetch it from the context.
__ lw(at, ContextOperand(cp, Context::CLOSURE_INDEX));
} else {
- ASSERT(declaration_scope->is_function_scope());
+ DCHECK(declaration_scope->is_function_scope());
__ lw(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
}
__ push(at);
@@ -4702,12 +4709,12 @@ void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
// Non-local control flow support.
void FullCodeGenerator::EnterFinallyBlock() {
- ASSERT(!result_register().is(a1));
+ DCHECK(!result_register().is(a1));
// Store result register while executing finally block.
__ push(result_register());
// Cook return address in link register to stack (smi encoded Code* delta).
__ Subu(a1, ra, Operand(masm_->CodeObject()));
- ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
+ DCHECK_EQ(1, kSmiTagSize + kSmiShiftSize);
STATIC_ASSERT(0 == kSmiTag);
__ Addu(a1, a1, Operand(a1)); // Convert to smi.
@@ -4737,7 +4744,7 @@ void FullCodeGenerator::EnterFinallyBlock() {
void FullCodeGenerator::ExitFinallyBlock() {
- ASSERT(!result_register().is(a1));
+ DCHECK(!result_register().is(a1));
// Restore pending message from stack.
__ pop(a1);
ExternalReference pending_message_script =
@@ -4763,7 +4770,7 @@ void FullCodeGenerator::ExitFinallyBlock() {
// Uncook return address and return.
__ pop(result_register());
- ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
+ DCHECK_EQ(1, kSmiTagSize + kSmiShiftSize);
__ sra(a1, a1, 1); // Un-smi-tag value.
__ Addu(at, a1, Operand(masm_->CodeObject()));
__ Jump(at);
@@ -4851,16 +4858,16 @@ BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState(
Address branch_address = pc - 6 * kInstrSize;
Address pc_immediate_load_address = pc - 4 * kInstrSize;
- ASSERT(Assembler::IsBeq(Assembler::instr_at(pc - 5 * kInstrSize)));
+ DCHECK(Assembler::IsBeq(Assembler::instr_at(pc - 5 * kInstrSize)));
if (!Assembler::IsAddImmediate(Assembler::instr_at(branch_address))) {
- ASSERT(reinterpret_cast<uint32_t>(
+ DCHECK(reinterpret_cast<uint32_t>(
Assembler::target_address_at(pc_immediate_load_address)) ==
reinterpret_cast<uint32_t>(
isolate->builtins()->InterruptCheck()->entry()));
return INTERRUPT;
}
- ASSERT(Assembler::IsAddImmediate(Assembler::instr_at(branch_address)));
+ DCHECK(Assembler::IsAddImmediate(Assembler::instr_at(branch_address)));
if (reinterpret_cast<uint32_t>(
Assembler::target_address_at(pc_immediate_load_address)) ==
@@ -4869,7 +4876,7 @@ BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState(
return ON_STACK_REPLACEMENT;
}
- ASSERT(reinterpret_cast<uint32_t>(
+ DCHECK(reinterpret_cast<uint32_t>(
Assembler::target_address_at(pc_immediate_load_address)) ==
reinterpret_cast<uint32_t>(
isolate->builtins()->OsrAfterStackCheck()->entry()));