diff options
Diffstat (limited to 'deps/v8/src/mips/full-codegen-mips.cc')
-rw-r--r-- | deps/v8/src/mips/full-codegen-mips.cc | 226 |
1 files changed, 106 insertions, 120 deletions
diff --git a/deps/v8/src/mips/full-codegen-mips.cc b/deps/v8/src/mips/full-codegen-mips.cc index 7368eada62..032c1f5e5b 100644 --- a/deps/v8/src/mips/full-codegen-mips.cc +++ b/deps/v8/src/mips/full-codegen-mips.cc @@ -27,7 +27,7 @@ #include "v8.h" -#if defined(V8_TARGET_ARCH_MIPS) +#if V8_TARGET_ARCH_MIPS // Note on Mips implementation: // @@ -138,7 +138,7 @@ void FullCodeGenerator::Generate() { CompilationInfo* info = info_; handler_table_ = isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); - profiling_counter_ = isolate()->factory()->NewJSGlobalPropertyCell( + profiling_counter_ = isolate()->factory()->NewCell( Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); SetFunctionPosition(function()); Comment cmnt(masm_, "[ function compiled by full code generator"); @@ -326,9 +326,9 @@ void FullCodeGenerator::ClearAccumulator() { void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { __ li(a2, Operand(profiling_counter_)); - __ lw(a3, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset)); + __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset)); __ Subu(a3, a3, Operand(Smi::FromInt(delta))); - __ sw(a3, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset)); + __ sw(a3, FieldMemOperand(a2, Cell::kValueOffset)); } @@ -344,7 +344,7 @@ void FullCodeGenerator::EmitProfilingCounterReset() { } __ li(a2, Operand(profiling_counter_)); __ li(a3, Operand(Smi::FromInt(reset_value))); - __ sw(a3, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset)); + __ sw(a3, FieldMemOperand(a2, Cell::kValueOffset)); } @@ -363,7 +363,7 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, ASSERT(back_edge_target->is_bound()); int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target); weight = Min(kMaxBackEdgeWeight, - Max(1, distance / kBackEdgeDistanceUnit)); + Max(1, distance / kCodeSizeMultiplier)); } EmitProfilingCounterDecrement(weight); __ slt(at, a3, zero_reg); @@ -406,7 +406,7 @@ void FullCodeGenerator::EmitReturnSequence() { } else if (FLAG_weighted_back_edges) { int distance = masm_->pc_offset(); weight = Min(kMaxBackEdgeWeight, - Max(1, distance / kBackEdgeDistanceUnit)); + Max(1, distance / kCodeSizeMultiplier)); } EmitProfilingCounterDecrement(weight); Label ok; @@ -1164,15 +1164,13 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { Label non_proxy; __ bind(&fixed_array); - Handle<JSGlobalPropertyCell> cell = - isolate()->factory()->NewJSGlobalPropertyCell( - Handle<Object>( - Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker), - isolate())); + Handle<Cell> cell = isolate()->factory()->NewCell( + Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker), + isolate())); RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); __ LoadHeapObject(a1, cell); __ li(a2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); - __ sw(a2, FieldMemOperand(a1, JSGlobalPropertyCell::kValueOffset)); + __ sw(a2, FieldMemOperand(a1, Cell::kValueOffset)); __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check __ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object @@ -1696,11 +1694,11 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); // Fall through. case ObjectLiteral::Property::COMPUTED: - if (key->handle()->IsInternalizedString()) { + if (key->value()->IsInternalizedString()) { if (property->emit_store()) { VisitForAccumulatorValue(value); __ mov(a0, result_register()); - __ li(a2, Operand(key->handle())); + __ li(a2, Operand(key->value())); __ lw(a1, MemOperand(sp)); Handle<Code> ic = is_classic_mode() ? isolate()->builtins()->StoreIC_Initialize() @@ -1836,13 +1834,11 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { Expression* subexpr = subexprs->at(i); // If the subexpression is a literal or a simple materialized literal it // is already set in the cloned array. - if (subexpr->AsLiteral() != NULL || - CompileTimeValue::IsCompileTimeValue(subexpr)) { - continue; - } + if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; if (!result_saved) { - __ push(v0); + __ push(v0); // array literal + __ Push(Smi::FromInt(expr->literal_index())); result_saved = true; } @@ -1850,7 +1846,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { if (IsFastObjectElementsKind(constant_elements_kind)) { int offset = FixedArray::kHeaderSize + (i * kPointerSize); - __ lw(t2, MemOperand(sp)); // Copy of array literal. + __ lw(t2, MemOperand(sp, kPointerSize)); // Copy of array literal. __ lw(a1, FieldMemOperand(t2, JSObject::kElementsOffset)); __ sw(result_register(), FieldMemOperand(a1, offset)); // Update the write barrier for the array store. @@ -1858,10 +1854,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { kRAHasBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET, INLINE_SMI_CHECK); } else { - __ lw(a1, MemOperand(sp)); // Copy of array literal. - __ lw(a2, FieldMemOperand(a1, JSObject::kMapOffset)); __ li(a3, Operand(Smi::FromInt(i))); - __ li(t0, Operand(Smi::FromInt(expr->literal_index()))); __ mov(a0, result_register()); StoreArrayLiteralElementStub stub; __ CallStub(&stub); @@ -1870,6 +1863,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); } if (result_saved) { + __ Pop(); // literal index context()->PlugTOS(); } else { context()->Plug(v0); @@ -1998,22 +1992,36 @@ void FullCodeGenerator::VisitYield(Yield* expr) { VisitForStackValue(expr->expression()); switch (expr->yield_kind()) { - case Yield::INITIAL: - case Yield::SUSPEND: { - VisitForStackValue(expr->generator_object()); - __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); - __ lw(context_register(), - MemOperand(fp, StandardFrameConstants::kContextOffset)); + case Yield::SUSPEND: + // Pop value from top-of-stack slot; box result into result register. + EmitCreateIteratorResult(false); + __ push(result_register()); + // Fall through. + case Yield::INITIAL: { + Label suspend, continuation, post_runtime, resume; - Label resume; - __ LoadRoot(at, Heap::kTheHoleValueRootIndex); - __ Branch(&resume, ne, result_register(), Operand(at)); - if (expr->yield_kind() == Yield::SUSPEND) { - EmitReturnIteratorResult(false); - } else { - __ pop(result_register()); - EmitReturnSequence(); - } + __ jmp(&suspend); + + __ bind(&continuation); + __ jmp(&resume); + + __ bind(&suspend); + VisitForAccumulatorValue(expr->generator_object()); + ASSERT(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)); + __ mov(a1, cp); + __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, + kRAHasBeenSaved, kDontSaveFPRegs); + __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); + __ Branch(&post_runtime, eq, sp, Operand(a1)); + __ push(v0); // generator object + __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); + __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); + __ bind(&post_runtime); + __ pop(result_register()); + EmitReturnSequence(); __ bind(&resume); context()->Plug(result_register()); @@ -2025,7 +2033,10 @@ void FullCodeGenerator::VisitYield(Yield* expr) { __ li(a1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed))); __ sw(a1, FieldMemOperand(result_register(), JSGeneratorObject::kContinuationOffset)); - EmitReturnIteratorResult(true); + // Pop value from top-of-stack slot, box result into result register. + EmitCreateIteratorResult(true); + EmitUnwindBeforeReturn(); + EmitReturnSequence(); break; } @@ -2036,83 +2047,70 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // [sp + 1 * kPointerSize] iter // [sp + 0 * kPointerSize] g - Label l_catch, l_try, l_resume, l_next, l_call, l_loop; + Label l_catch, l_try, l_suspend, l_continuation, l_resume; + Label l_next, l_call, l_loop; // Initial send value is undefined. __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); __ Branch(&l_next); - // catch (e) { receiver = iter; f = iter.throw; arg = e; goto l_call; } + // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } __ 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(a3); // iter __ push(a0); // exception - __ mov(a0, a3); // iter - __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw" - Handle<Code> throw_ic = isolate()->builtins()->LoadIC_Initialize(); - CallIC(throw_ic); // iter.throw in a0 - __ mov(a0, v0); __ jmp(&l_call); - // try { received = yield result.value } + // try { received = %yield result } + // Shuffle the received result above a try handler and yield it without + // re-boxing. __ bind(&l_try); - __ pop(a0); // result.value + __ pop(a0); // result __ PushTryHandler(StackHandler::CATCH, expr->index()); const int handler_size = StackHandlerConstants::kSize; - __ push(a0); // result.value - __ lw(a3, MemOperand(sp, (0 + 1) * kPointerSize + handler_size)); // g - __ push(a3); // g - __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); + __ push(a0); // result + __ jmp(&l_suspend); + __ bind(&l_continuation); __ mov(a0, v0); - __ lw(context_register(), - MemOperand(fp, StandardFrameConstants::kContextOffset)); - __ LoadRoot(at, Heap::kTheHoleValueRootIndex); - __ Branch(&l_resume, ne, a0, Operand(at)); - EmitReturnIteratorResult(false); + __ jmp(&l_resume); + __ bind(&l_suspend); + 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())); + __ 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::kSuspendJSGeneratorObject, 1); + __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); + __ pop(v0); // result + EmitReturnSequence(); __ mov(a0, v0); __ bind(&l_resume); // received in a0 __ PopTryHandler(); - // receiver = iter; f = iter.next; arg = received; + // receiver = iter; f = 'next'; arg = received; __ bind(&l_next); + __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter __ push(a3); // iter __ push(a0); // received - __ mov(a0, a3); // iter - __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" - Handle<Code> next_ic = isolate()->builtins()->LoadIC_Initialize(); - CallIC(next_ic); // iter.next in a0 - __ mov(a0, v0); - // result = f.call(receiver, arg); + // result = receiver[f](arg); __ bind(&l_call); - Label l_call_runtime; - __ JumpIfSmi(a0, &l_call_runtime); - __ GetObjectType(a0, a1, a1); - __ Branch(&l_call_runtime, ne, a1, Operand(JS_FUNCTION_TYPE)); - __ mov(a1, a0); - ParameterCount count(1); - __ InvokeFunction(a1, count, CALL_FUNCTION, - NullCallWrapper(), CALL_AS_METHOD); + Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); + CallIC(ic); __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); - __ jmp(&l_loop); - __ bind(&l_call_runtime); - __ push(a0); - __ CallRuntime(Runtime::kCall, 3); - // val = result.value; if (!result.done) goto l_try; + // if (!result.done) goto l_try; __ bind(&l_loop); __ mov(a0, v0); - // result.value __ push(a0); // save result - __ LoadRoot(a2, Heap::kvalue_stringRootIndex); // "value" - Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize(); - CallIC(value_ic); // result.value in a0 - __ mov(a0, v0); - __ pop(a1); // result - __ push(a0); // result.value - __ mov(a0, a1); // result __ LoadRoot(a2, Heap::kdone_stringRootIndex); // "done" Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize(); CallIC(done_ic); // result.done in v0 @@ -2122,7 +2120,10 @@ void FullCodeGenerator::VisitYield(Yield* expr) { __ Branch(&l_try, eq, v0, Operand(zero_reg)); // result.value - __ pop(v0); // result.value + __ pop(a0); // result + __ LoadRoot(a2, Heap::kvalue_stringRootIndex); // "value" + Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize(); + CallIC(value_ic); // result.value in v0 context()->DropAndPlug(2, v0); // drop iter and g break; } @@ -2162,7 +2163,7 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator, __ LoadRoot(a2, Heap::kTheHoleValueRootIndex); Label push_argument_holes, push_frame; __ bind(&push_argument_holes); - __ Subu(a3, a3, Operand(1)); + __ Subu(a3, a3, Operand(Smi::FromInt(1))); __ Branch(&push_frame, lt, a3, Operand(zero_reg)); __ push(a2); __ jmp(&push_argument_holes); @@ -2226,13 +2227,20 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator, } -void FullCodeGenerator::EmitReturnIteratorResult(bool done) { +void FullCodeGenerator::EmitCreateIteratorResult(bool done) { Label gc_required; Label allocated; Handle<Map> map(isolate()->native_context()->generator_result_map()); __ Allocate(map->instance_size(), a0, a2, a3, &gc_required, TAG_OBJECT); + __ jmp(&allocated); + + __ bind(&gc_required); + __ Push(Smi::FromInt(map->instance_size())); + __ CallRuntime(Runtime::kAllocateInNewSpace, 1); + __ lw(context_register(), + MemOperand(fp, StandardFrameConstants::kContextOffset)); __ bind(&allocated); __ li(a1, Operand(map)); @@ -2252,27 +2260,7 @@ void FullCodeGenerator::EmitReturnIteratorResult(bool done) { // root set. __ RecordWriteField(a0, JSGeneratorObject::kResultValuePropertyOffset, a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); - - if (done) { - // Exit all nested statements. - NestedStatement* current = nesting_stack_; - int stack_depth = 0; - int context_length = 0; - while (current != NULL) { - current = current->Exit(&stack_depth, &context_length); - } - __ Drop(stack_depth); - } - __ mov(result_register(), a0); - EmitReturnSequence(); - - __ bind(&gc_required); - __ Push(Smi::FromInt(map->instance_size())); - __ CallRuntime(Runtime::kAllocateInNewSpace, 1); - __ lw(context_register(), - MemOperand(fp, StandardFrameConstants::kContextOffset)); - __ jmp(&allocated); } @@ -2280,7 +2268,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { SetSourcePosition(prop->position()); Literal* key = prop->key()->AsLiteral(); __ mov(a0, result_register()); - __ li(a2, Operand(key->handle())); + __ li(a2, Operand(key->value())); // Call load IC. It has arguments receiver and property name a0 and a2. Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); @@ -2442,7 +2430,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) { VisitForAccumulatorValue(prop->obj()); __ mov(a1, result_register()); __ pop(a0); // Restore value. - __ li(a2, Operand(prop->key()->AsLiteral()->handle())); + __ li(a2, Operand(prop->key()->AsLiteral()->value())); Handle<Code> ic = is_classic_mode() ? isolate()->builtins()->StoreIC_Initialize() : isolate()->builtins()->StoreIC_Initialize_Strict(); @@ -2573,7 +2561,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { // Record source code position before IC call. SetSourcePosition(expr->position()); __ mov(a0, result_register()); // Load the value. - __ li(a2, Operand(prop->key()->AsLiteral()->handle())); + __ li(a2, Operand(prop->key()->AsLiteral()->value())); __ pop(a1); Handle<Code> ic = is_classic_mode() @@ -2711,8 +2699,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); Handle<Object> uninitialized = TypeFeedbackCells::UninitializedSentinel(isolate()); - Handle<JSGlobalPropertyCell> cell = - isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); + Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); __ li(a2, Operand(cell)); @@ -2852,7 +2839,7 @@ void FullCodeGenerator::VisitCall(Call* expr) { } if (property->key()->IsPropertyName()) { EmitCallWithIC(expr, - property->key()->AsLiteral()->handle(), + property->key()->AsLiteral()->value(), RelocInfo::CODE_TARGET); } else { EmitKeyedCallWithIC(expr, property->key()); @@ -2906,8 +2893,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) { // Record call targets in unoptimized code. Handle<Object> uninitialized = TypeFeedbackCells::UninitializedSentinel(isolate()); - Handle<JSGlobalPropertyCell> cell = - isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); + Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); __ li(a2, Operand(cell)); @@ -3458,7 +3444,7 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) { ZoneList<Expression*>* args = expr->arguments(); ASSERT(args->length() == 2); ASSERT_NE(NULL, args->at(1)->AsLiteral()); - Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->handle())); + Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value())); VisitForAccumulatorValue(args->at(0)); // Load the object. @@ -3890,7 +3876,7 @@ void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { ASSERT_EQ(2, args->length()); ASSERT_NE(NULL, args->at(0)->AsLiteral()); - int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); + int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value(); Handle<FixedArray> jsfunction_result_caches( isolate()->native_context()->jsfunction_result_caches()); @@ -4565,7 +4551,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { break; case NAMED_PROPERTY: { __ mov(a0, result_register()); // Value. - __ li(a2, Operand(prop->key()->AsLiteral()->handle())); // Name. + __ li(a2, Operand(prop->key()->AsLiteral()->value())); // Name. __ pop(a1); // Receiver. Handle<Code> ic = is_classic_mode() ? isolate()->builtins()->StoreIC_Initialize() |