diff options
Diffstat (limited to 'deps/v8/src/arm/lithium-codegen-arm.cc')
-rw-r--r-- | deps/v8/src/arm/lithium-codegen-arm.cc | 234 |
1 files changed, 126 insertions, 108 deletions
diff --git a/deps/v8/src/arm/lithium-codegen-arm.cc b/deps/v8/src/arm/lithium-codegen-arm.cc index d2f44b05c0..29e01b9182 100644 --- a/deps/v8/src/arm/lithium-codegen-arm.cc +++ b/deps/v8/src/arm/lithium-codegen-arm.cc @@ -238,7 +238,12 @@ bool LCodeGen::GeneratePrologue() { __ str(r0, target); // Update the write barrier. This clobbers r3 and r0. __ RecordWriteContextSlot( - cp, target.offset(), r0, r3, GetLinkRegisterState(), kSaveFPRegs); + cp, + target.offset(), + r0, + r3, + GetLinkRegisterState(), + kSaveFPRegs); } } Comment(";;; End allocate local context"); @@ -259,38 +264,21 @@ bool LCodeGen::GenerateBody() { !is_aborted() && current_instruction_ < instructions_->length(); current_instruction_++) { LInstruction* instr = instructions_->at(current_instruction_); + + // Don't emit code for basic blocks with a replacement. if (instr->IsLabel()) { - LLabel* label = LLabel::cast(instr); - emit_instructions = !label->HasReplacement(); + emit_instructions = !LLabel::cast(instr)->HasReplacement(); } + if (!emit_instructions) continue; - if (emit_instructions) { - if (FLAG_code_comments) { - HValue* hydrogen = instr->hydrogen_value(); - if (hydrogen != NULL) { - if (hydrogen->IsChange()) { - HValue* changed_value = HChange::cast(hydrogen)->value(); - int use_id = 0; - const char* use_mnemo = "dead"; - if (hydrogen->UseCount() >= 1) { - HValue* use_value = hydrogen->uses().value(); - use_id = use_value->id(); - use_mnemo = use_value->Mnemonic(); - } - Comment(";;; @%d: %s. <of #%d %s for #%d %s>", - current_instruction_, instr->Mnemonic(), - changed_value->id(), changed_value->Mnemonic(), - use_id, use_mnemo); - } else { - Comment(";;; @%d: %s. <#%d>", current_instruction_, - instr->Mnemonic(), hydrogen->id()); - } - } else { - Comment(";;; @%d: %s.", current_instruction_, instr->Mnemonic()); - } - } - instr->CompileToNative(this); + if (FLAG_code_comments && instr->HasInterestingComment(this)) { + Comment(";;; <@%d,#%d> %s", + current_instruction_, + instr->hydrogen_value()->id(), + instr->Mnemonic()); } + + instr->CompileToNative(this); } EnsureSpaceForLazyDeopt(); return !is_aborted(); @@ -302,11 +290,14 @@ bool LCodeGen::GenerateDeferredCode() { if (deferred_.length() > 0) { for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { LDeferredCode* code = deferred_[i]; + Comment(";;; <@%d,#%d> " + "-------------------- Deferred %s --------------------", + code->instruction_index(), + code->instr()->hydrogen_value()->id(), + code->instr()->Mnemonic()); __ bind(code->entry()); if (NeedsDeferredFrame()) { - Comment(";;; Deferred build frame @%d: %s.", - code->instruction_index(), - code->instr()->Mnemonic()); + Comment(";;; Build frame"); ASSERT(!frame_is_built_); ASSERT(info()->IsStub()); frame_is_built_ = true; @@ -314,15 +305,11 @@ bool LCodeGen::GenerateDeferredCode() { __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); __ push(scratch0()); __ add(fp, sp, Operand(2 * kPointerSize)); + Comment(";;; Deferred code"); } - Comment(";;; Deferred code @%d: %s.", - code->instruction_index(), - code->instr()->Mnemonic()); code->Generate(); if (NeedsDeferredFrame()) { - Comment(";;; Deferred destroy frame @%d: %s.", - code->instruction_index(), - code->instr()->Mnemonic()); + Comment(";;; Destroy frame"); ASSERT(frame_is_built_); __ pop(ip); __ ldm(ia_w, sp, cp.bit() | fp.bit() | lr.bit()); @@ -353,7 +340,9 @@ bool LCodeGen::GenerateDeoptJumpTable() { Abort("Generated code is too large"); } - __ RecordComment("[ Deoptimisation jump table"); + if (deopt_jump_table_.length() > 0) { + Comment(";;; -------------------- Jump table --------------------"); + } Label table_start; __ bind(&table_start); Label needs_frame_not_call; @@ -414,7 +403,6 @@ bool LCodeGen::GenerateDeoptJumpTable() { } masm()->CheckConstPool(false, false); } - __ RecordComment("]"); // Force constant pool emission at the end of the deopt jump table to make // sure that no constant pools are emitted after. @@ -607,7 +595,7 @@ void LCodeGen::WriteTranslation(LEnvironment* environment, pushed_arguments_index, pushed_arguments_count); bool has_closure_id = !info()->closure().is_null() && - *info()->closure() != *environment->closure(); + !info()->closure().is_identical_to(environment->closure()); int closure_id = has_closure_id ? DefineDeoptimizationLiteral(environment->closure()) : Translation::kSelfLiteralId; @@ -923,10 +911,13 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { Handle<FixedArray> literals = factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); - for (int i = 0; i < deoptimization_literals_.length(); i++) { - literals->set(i, *deoptimization_literals_[i]); + { ALLOW_HANDLE_DEREF(isolate(), + "copying a ZoneList of handles into a FixedArray"); + for (int i = 0; i < deoptimization_literals_.length(); i++) { + literals->set(i, *deoptimization_literals_[i]); + } + data->SetLiteralArray(*literals); } - data->SetLiteralArray(*literals); data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); @@ -1042,10 +1033,19 @@ void LCodeGen::RecordPosition(int position) { } +static const char* LabelType(LLabel* label) { + if (label->is_loop_header()) return " (loop header)"; + if (label->is_osr_entry()) return " (OSR entry)"; + return ""; +} + + void LCodeGen::DoLabel(LLabel* label) { - Comment(";;; -------------------- B%d%s --------------------", + Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", + current_instruction_, + label->hydrogen_value()->id(), label->block_id(), - label->is_loop_header() ? " (loop header)" : ""); + LabelType(label)); __ bind(label->label()); current_block_ = label->block_id(); DoGap(label); @@ -1904,6 +1904,7 @@ void LCodeGen::DoConstantD(LConstantD* instr) { void LCodeGen::DoConstantT(LConstantT* instr) { Handle<Object> value = instr->value(); + ALLOW_HANDLE_DEREF(isolate(), "smi check"); if (value->IsSmi()) { __ mov(ToRegister(instr->result()), Operand(value)); } else { @@ -2170,17 +2171,16 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) { } -int LCodeGen::GetNextEmittedBlock(int block) { - for (int i = block + 1; i < graph()->blocks()->length(); ++i) { - LLabel* label = chunk_->GetLabel(i); - if (!label->HasReplacement()) return i; +int LCodeGen::GetNextEmittedBlock() const { + for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { + if (!chunk_->GetLabel(i)->HasReplacement()) return i; } return -1; } void LCodeGen::EmitBranch(int left_block, int right_block, Condition cc) { - int next_block = GetNextEmittedBlock(current_block_); + int next_block = GetNextEmittedBlock(); right_block = chunk_->LookupDestination(right_block); left_block = chunk_->LookupDestination(left_block); @@ -2317,10 +2317,8 @@ void LCodeGen::DoBranch(LBranch* instr) { void LCodeGen::EmitGoto(int block) { - block = chunk_->LookupDestination(block); - int next_block = GetNextEmittedBlock(current_block_); - if (block != next_block) { - __ jmp(chunk_->GetAssemblyLabel(block)); + if (!IsNextEmittedBlock(block)) { + __ jmp(chunk_->GetAssemblyLabel(chunk_->LookupDestination(block))); } } @@ -2944,19 +2942,20 @@ void LCodeGen::DoReturn(LReturn* instr) { if (NeedsEagerFrame()) { __ mov(sp, fp); __ ldm(ia_w, sp, fp.bit() | lr.bit()); - - if (instr->has_constant_parameter_count()) { - int parameter_count = ToInteger32(instr->constant_parameter_count()); - int32_t sp_delta = (parameter_count + 1) * kPointerSize; - if (sp_delta != 0) { - __ add(sp, sp, Operand(sp_delta)); - } - } else { - Register reg = ToRegister(instr->parameter_count()); - __ add(reg, reg, Operand(1)); - __ add(sp, sp, Operand(reg, LSL, kPointerSizeLog2)); + } + if (instr->has_constant_parameter_count()) { + int parameter_count = ToInteger32(instr->constant_parameter_count()); + int32_t sp_delta = (parameter_count + 1) * kPointerSize; + if (sp_delta != 0) { + __ add(sp, sp, Operand(sp_delta)); } + } else { + Register reg = ToRegister(instr->parameter_count()); + // The argument count parameter is a smi + __ SmiUntag(reg); + __ add(sp, sp, Operand(reg, LSL, kPointerSizeLog2)); } + __ Jump(lr); } @@ -3274,14 +3273,22 @@ void LCodeGen::DoLoadExternalArrayPointer( void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { Register arguments = ToRegister(instr->arguments()); - Register length = ToRegister(instr->length()); - Register index = ToRegister(instr->index()); Register result = ToRegister(instr->result()); - // There are two words between the frame pointer and the last argument. - // Subtracting from length accounts for one of them add one more. - __ sub(length, length, index); - __ add(length, length, Operand(1)); - __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2)); + if (instr->length()->IsConstantOperand() && + instr->index()->IsConstantOperand()) { + int const_index = ToInteger32(LConstantOperand::cast(instr->index())); + int const_length = ToInteger32(LConstantOperand::cast(instr->length())); + int index = (const_length - const_index) + 1; + __ ldr(result, MemOperand(arguments, index * kPointerSize)); + } else { + Register length = ToRegister(instr->length()); + Register index = ToRegister(instr->index()); + // There are two words between the frame pointer and the last argument. + // Subtracting from length accounts for one of them add one more. + __ sub(length, length, index); + __ add(length, length, Operand(1)); + __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2)); + } } @@ -3703,12 +3710,15 @@ void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { void LCodeGen::CallKnownFunction(Handle<JSFunction> function, + int formal_parameter_count, int arity, LInstruction* instr, CallKind call_kind, R1State r1_state) { - bool can_invoke_directly = !function->NeedsArgumentsAdaption() || - function->shared()->formal_parameter_count() == arity; + bool dont_adapt_arguments = + formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; + bool can_invoke_directly = + dont_adapt_arguments || formal_parameter_count == arity; LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); @@ -3723,7 +3733,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, // Set r0 to arguments count if adaption is not needed. Assumes that r0 // is available to write to at this point. - if (!function->NeedsArgumentsAdaption()) { + if (dont_adapt_arguments) { __ mov(r0, Operand(arity)); } @@ -3737,7 +3747,9 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, } else { SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); ParameterCount count(arity); - __ InvokeFunction(function, count, CALL_FUNCTION, generator, call_kind); + ParameterCount expected(formal_parameter_count); + __ InvokeFunction( + function, expected, count, CALL_FUNCTION, generator, call_kind); } // Restore context. @@ -3747,7 +3759,8 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { ASSERT(ToRegister(instr->result()).is(r0)); - CallKnownFunction(instr->function(), + CallKnownFunction(instr->hydrogen()->function(), + instr->hydrogen()->formal_parameter_count(), instr->arity(), instr, CALL_AS_METHOD, @@ -4119,7 +4132,8 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { ASSERT(ToRegister(instr->function()).is(r1)); ASSERT(instr->HasPointerMap()); - if (instr->known_function().is_null()) { + Handle<JSFunction> known_function = instr->hydrogen()->known_function(); + if (known_function.is_null()) { LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); @@ -4127,7 +4141,8 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); } else { - CallKnownFunction(instr->known_function(), + CallKnownFunction(known_function, + instr->hydrogen()->formal_parameter_count(), instr->arity(), instr, CALL_AS_METHOD, @@ -4187,7 +4202,8 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { ASSERT(ToRegister(instr->result()).is(r0)); - CallKnownFunction(instr->target(), + CallKnownFunction(instr->hydrogen()->target(), + instr->hydrogen()->formal_parameter_count(), instr->arity(), instr, CALL_AS_FUNCTION, @@ -4218,10 +4234,18 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) { __ mov(r0, Operand(instr->arity())); __ mov(r2, Operand(instr->hydrogen()->property_cell())); - Handle<Code> array_construct_code = - isolate()->builtins()->ArrayConstructCode(); - - CallCode(array_construct_code, RelocInfo::CONSTRUCT_CALL, instr); + Object* cell_value = instr->hydrogen()->property_cell()->value(); + ElementsKind kind = static_cast<ElementsKind>(Smi::cast(cell_value)->value()); + if (instr->arity() == 0) { + ArrayNoArgumentConstructorStub stub(kind); + CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); + } else if (instr->arity() == 1) { + ArraySingleArgumentConstructorStub stub(kind); + CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); + } else { + ArrayNArgumentsConstructorStub stub(kind); + CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); + } } @@ -5038,8 +5062,8 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { __ sub(scratch1, input_reg, Operand(kHeapObjectTag)); __ vldr(double_scratch2, scratch1, HeapNumber::kValueOffset); - __ ECMAToInt32(input_reg, double_scratch2, double_scratch, - scratch1, scratch2, scratch3); + __ ECMAToInt32(input_reg, double_scratch2, + scratch1, scratch2, scratch3, double_scratch); } else { // Deoptimize if we don't have a heap number. @@ -5136,8 +5160,8 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) { if (instr->truncating()) { Register scratch3 = ToRegister(instr->temp2()); - __ ECMAToInt32(result_reg, double_input, double_scratch, - scratch1, scratch2, scratch3); + __ ECMAToInt32(result_reg, double_input, + scratch1, scratch2, scratch3, double_scratch); } else { __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch); // Deoptimize if the input wasn't a int32 (inside a double). @@ -5207,6 +5231,7 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { void LCodeGen::DoCheckFunction(LCheckFunction* instr) { Register reg = ToRegister(instr->value()); Handle<JSFunction> target = instr->hydrogen()->target(); + ALLOW_HANDLE_DEREF(isolate(), "smi check"); if (isolate()->heap()->InNewSpace(*target)) { Register reg = ToRegister(instr->value()); Handle<JSGlobalPropertyCell> cell = @@ -5348,16 +5373,12 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) { Register scratch = ToRegister(instr->temp()); Register scratch2 = ToRegister(instr->temp2()); Handle<JSFunction> constructor = instr->hydrogen()->constructor(); - Handle<Map> initial_map(constructor->initial_map()); + Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map(); int instance_size = initial_map->instance_size(); ASSERT(initial_map->pre_allocated_property_fields() + initial_map->unused_property_fields() - initial_map->inobject_properties() == 0); - // Allocate memory for the object. The initial map might change when - // the constructor's prototype changes, but instance size and property - // counts remain unchanged (if slack tracking finished). - ASSERT(!constructor->shared()->IsInobjectSlackTrackingInProgress()); __ Allocate(instance_size, result, scratch, scratch2, deferred->entry(), TAG_OBJECT); @@ -5392,8 +5413,7 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) { void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { Register result = ToRegister(instr->result()); - Handle<JSFunction> constructor = instr->hydrogen()->constructor(); - Handle<Map> initial_map(constructor->initial_map()); + Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map(); int instance_size = initial_map->instance_size(); // TODO(3095996): Get rid of this. For now, we need to make the @@ -5476,7 +5496,7 @@ void LCodeGen::DoDeferredAllocate(LAllocate* instr) { void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { - Handle<FixedArray> literals(instr->environment()->closure()->literals()); + Handle<FixedArray> literals = instr->hydrogen()->literals(); ElementsKind boilerplate_elements_kind = instr->hydrogen()->boilerplate_elements_kind(); AllocationSiteMode allocation_site_mode = @@ -5531,7 +5551,7 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { - Handle<FixedArray> literals(instr->environment()->closure()->literals()); + Handle<FixedArray> literals = instr->hydrogen()->literals(); Handle<FixedArray> constant_properties = instr->hydrogen()->constant_properties(); @@ -5545,7 +5565,7 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { __ mov(r0, Operand(Smi::FromInt(flags))); // Pick the right runtime function or stub to call. - int properties_count = constant_properties->length() / 2; + int properties_count = instr->hydrogen()->constant_properties_length() / 2; if (instr->hydrogen()->depth() > 1) { __ Push(r3, r2, r1, r0); CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); @@ -5614,19 +5634,17 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { // Use the fast case closure allocation code that allocates in new // space for nested functions that don't need literals cloning. - Handle<SharedFunctionInfo> shared_info = instr->shared_info(); bool pretenure = instr->hydrogen()->pretenure(); - if (!pretenure && shared_info->num_literals() == 0) { - FastNewClosureStub stub(shared_info->language_mode(), - shared_info->is_generator()); - __ mov(r1, Operand(shared_info)); + if (!pretenure && instr->hydrogen()->has_no_literals()) { + FastNewClosureStub stub(instr->hydrogen()->language_mode(), + instr->hydrogen()->is_generator()); + __ mov(r1, Operand(instr->hydrogen()->shared_info())); __ push(r1); CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); } else { - __ mov(r2, Operand(shared_info)); - __ mov(r1, Operand(pretenure - ? factory()->true_value() - : factory()->false_value())); + __ mov(r2, Operand(instr->hydrogen()->shared_info())); + __ mov(r1, Operand(pretenure ? factory()->true_value() + : factory()->false_value())); __ Push(cp, r2, r1); CallRuntime(Runtime::kNewClosure, 3, instr); } |