diff options
Diffstat (limited to 'deps/v8/src/arm/full-codegen-arm.cc')
-rw-r--r-- | deps/v8/src/arm/full-codegen-arm.cc | 212 |
1 files changed, 96 insertions, 116 deletions
diff --git a/deps/v8/src/arm/full-codegen-arm.cc b/deps/v8/src/arm/full-codegen-arm.cc index 3b560fedfa..be8228377a 100644 --- a/deps/v8/src/arm/full-codegen-arm.cc +++ b/deps/v8/src/arm/full-codegen-arm.cc @@ -130,7 +130,7 @@ void FullCodeGenerator::Generate() { handler_table_ = isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); profiling_counter_ = isolate()->factory()->NewJSGlobalPropertyCell( - Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); + Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget))); SetFunctionPosition(function()); Comment cmnt(masm_, "[ function compiled by full code generator"); @@ -164,19 +164,14 @@ void FullCodeGenerator::Generate() { int locals_count = info->scope()->num_stack_slots(); - info->set_prologue_offset(masm_->pc_offset()); - { - PredictableCodeSizeScope predictible_code_size_scope( - masm_, kNoCodeAgeSequenceLength * Assembler::kInstrSize); - // The following three instructions must remain together and unmodified - // for code aging to work properly. - __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); + __ Push(lr, fp, cp, r1); + if (locals_count > 0) { // Load undefined value here, so the value is ready for the loop // below. __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); - // Adjust FP to point to saved FP. - __ add(fp, sp, Operand(2 * kPointerSize)); } + // Adjust fp to point to caller's fp. + __ add(fp, sp, Operand(2 * kPointerSize)); { Comment cmnt(masm_, "[ Allocate locals"); for (int i = 0; i < locals_count; i++) { @@ -292,7 +287,7 @@ void FullCodeGenerator::Generate() { __ LoadRoot(ip, Heap::kStackLimitRootIndex); __ cmp(sp, Operand(ip)); __ b(hs, &ok); - PredictableCodeSizeScope predictable(masm_, 2 * Assembler::kInstrSize); + PredictableCodeSizeScope predictable(masm_); StackCheckStub stub; __ CallStub(&stub); __ bind(&ok); @@ -347,31 +342,42 @@ void FullCodeGenerator::EmitProfilingCounterReset() { } -void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, - Label* back_edge_target) { - Comment cmnt(masm_, "[ Back edge bookkeeping"); +void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt, + Label* back_edge_target) { + Comment cmnt(masm_, "[ Stack check"); // Block literal pools whilst emitting stack check code. Assembler::BlockConstPoolScope block_const_pool(masm_); Label ok; - int weight = 1; - if (FLAG_weighted_back_edges) { - ASSERT(back_edge_target->is_bound()); - int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target); - weight = Min(kMaxBackEdgeWeight, - Max(1, distance / kBackEdgeDistanceUnit)); + if (FLAG_count_based_interrupts) { + int weight = 1; + if (FLAG_weighted_back_edges) { + ASSERT(back_edge_target->is_bound()); + int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target); + weight = Min(kMaxBackEdgeWeight, + Max(1, distance / kBackEdgeDistanceUnit)); + } + EmitProfilingCounterDecrement(weight); + __ b(pl, &ok); + InterruptStub stub; + __ CallStub(&stub); + } else { + __ LoadRoot(ip, Heap::kStackLimitRootIndex); + __ cmp(sp, Operand(ip)); + __ b(hs, &ok); + PredictableCodeSizeScope predictable(masm_); + StackCheckStub stub; + __ CallStub(&stub); } - EmitProfilingCounterDecrement(weight); - __ b(pl, &ok); - InterruptStub stub; - __ CallStub(&stub); // Record a mapping of this PC offset to the OSR id. This is used to find // the AST id from the unoptimized code in order to use it as a key into // the deoptimization input data found in the optimized code. - RecordBackEdge(stmt->OsrEntryId()); + RecordStackCheck(stmt->OsrEntryId()); - EmitProfilingCounterReset(); + if (FLAG_count_based_interrupts) { + EmitProfilingCounterReset(); + } __ bind(&ok); PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); @@ -433,8 +439,7 @@ void FullCodeGenerator::EmitReturnSequence() { // tool from instrumenting as we rely on the code size here. int32_t sp_delta = (info_->scope()->num_parameters() + 1) * kPointerSize; CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); - // TODO(svenpanne) The code below is sometimes 4 words, sometimes 5! - PredictableCodeSizeScope predictable(masm_, -1); + PredictableCodeSizeScope predictable(masm_); __ RecordJSReturn(); masm_->mov(sp, fp); masm_->ldm(ia_w, sp, fp.bit() | lr.bit()); @@ -909,33 +914,34 @@ void FullCodeGenerator::VisitFunctionDeclaration( void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { - Variable* variable = declaration->proxy()->var(); - ASSERT(variable->location() == Variable::CONTEXT); - ASSERT(variable->interface()->IsFrozen()); - - Comment cmnt(masm_, "[ ModuleDeclaration"); - EmitDebugCheckDeclarationContext(variable); + VariableProxy* proxy = declaration->proxy(); + Variable* variable = proxy->var(); + Handle<JSModule> instance = declaration->module()->interface()->Instance(); + ASSERT(!instance.is_null()); - // Load instance object. - __ LoadContext(r1, scope_->ContextChainLength(scope_->GlobalScope())); - __ ldr(r1, ContextOperand(r1, variable->interface()->Index())); - __ ldr(r1, ContextOperand(r1, Context::EXTENSION_INDEX)); + switch (variable->location()) { + case Variable::UNALLOCATED: { + Comment cmnt(masm_, "[ ModuleDeclaration"); + globals_->Add(variable->name(), zone()); + globals_->Add(instance, zone()); + Visit(declaration->module()); + break; + } - // Assign it. - __ str(r1, ContextOperand(cp, variable->index())); - // We know that we have written a module, which is not a smi. - __ RecordWriteContextSlot(cp, - Context::SlotOffset(variable->index()), - r1, - r3, - kLRHasBeenSaved, - kDontSaveFPRegs, - EMIT_REMEMBERED_SET, - OMIT_SMI_CHECK); - PrepareForBailoutForId(declaration->proxy()->id(), NO_REGISTERS); + case Variable::CONTEXT: { + Comment cmnt(masm_, "[ ModuleDeclaration"); + EmitDebugCheckDeclarationContext(variable); + __ mov(r1, Operand(instance)); + __ str(r1, ContextOperand(cp, variable->index())); + Visit(declaration->module()); + break; + } - // Traverse into body. - Visit(declaration->module()); + case Variable::PARAMETER: + case Variable::LOCAL: + case Variable::LOOKUP: + UNREACHABLE(); + } } @@ -978,14 +984,6 @@ void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { } -void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { - // Call the runtime to declare the modules. - __ Push(descriptions); - __ CallRuntime(Runtime::kDeclareModules, 1); - // Return value is ignored. -} - - void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { Comment cmnt(masm_, "[ SwitchStatement"); Breakable nested_statement(this, stmt); @@ -1240,7 +1238,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ add(r0, r0, Operand(Smi::FromInt(1))); __ push(r0); - EmitBackEdgeBookkeeping(stmt, &loop); + EmitStackCheck(stmt, &loop); __ b(&loop); // Remove the pointers stored on the stack. @@ -1393,9 +1391,9 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(Variable* var, } else if (var->mode() == DYNAMIC_LOCAL) { Variable* local = var->local_if_not_shadowed(); __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow)); - if (local->mode() == LET || - local->mode() == CONST || - local->mode() == CONST_HARMONY) { + if (local->mode() == CONST || + local->mode() == CONST_HARMONY || + local->mode() == LET) { __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); if (local->mode() == CONST) { __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); @@ -2376,7 +2374,7 @@ void FullCodeGenerator::VisitCall(Call* expr) { VariableProxy* proxy = callee->AsVariableProxy(); Property* property = callee->AsProperty(); - if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { + if (proxy != NULL && proxy->var()->is_possibly_eval()) { // In a call to eval, we first call %ResolvePossiblyDirectEval to // resolve the function we need to call and the receiver of the // call. Then we call the resolved function using the given @@ -3131,39 +3129,6 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) { } -void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { - ZoneList<Expression*>* args = expr->arguments(); - ASSERT_EQ(3, args->length()); - - VisitForStackValue(args->at(1)); // index - VisitForStackValue(args->at(2)); // value - __ pop(r2); - __ pop(r1); - VisitForAccumulatorValue(args->at(0)); // string - - static const String::Encoding encoding = String::ONE_BYTE_ENCODING; - SeqStringSetCharGenerator::Generate(masm_, encoding, r0, r1, r2); - context()->Plug(r0); -} - - -void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { - ZoneList<Expression*>* args = expr->arguments(); - ASSERT_EQ(3, args->length()); - - VisitForStackValue(args->at(1)); // index - VisitForStackValue(args->at(2)); // value - __ pop(r2); - __ pop(r1); - VisitForAccumulatorValue(args->at(0)); // string - - static const String::Encoding encoding = String::TWO_BYTE_ENCODING; - SeqStringSetCharGenerator::Generate(masm_, encoding, r0, r1, r2); - context()->Plug(r0); -} - - - void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { // Load the arguments on the stack and call the runtime function. ZoneList<Expression*>* args = expr->arguments(); @@ -3656,7 +3621,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { __ ldr(scratch1, FieldMemOperand(string, HeapObject::kMapOffset)); __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout); - __ ldr(scratch1, FieldMemOperand(string, SeqOneByteString::kLengthOffset)); + __ ldr(scratch1, FieldMemOperand(string, SeqAsciiString::kLengthOffset)); __ add(string_length, string_length, Operand(scratch1), SetCC); __ b(vs, &bailout); __ cmp(element, elements_end); @@ -3685,7 +3650,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { // Add (separator length times array_length) - separator length to the // string_length to get the length of the result string. array_length is not // smi but the other values are, so the result is a smi - __ ldr(scratch1, FieldMemOperand(separator, SeqOneByteString::kLengthOffset)); + __ ldr(scratch1, FieldMemOperand(separator, SeqAsciiString::kLengthOffset)); __ sub(string_length, string_length, Operand(scratch1)); __ smull(scratch2, ip, array_length, scratch1); // Check for smi overflow. No overflow if higher 33 bits of 64-bit result are @@ -3723,10 +3688,10 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { array_length = no_reg; __ add(result_pos, result, - Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); + Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); // Check the length of the separator. - __ ldr(scratch1, FieldMemOperand(separator, SeqOneByteString::kLengthOffset)); + __ ldr(scratch1, FieldMemOperand(separator, SeqAsciiString::kLengthOffset)); __ cmp(scratch1, Operand(Smi::FromInt(1))); __ b(eq, &one_char_separator); __ b(gt, &long_separator); @@ -3742,9 +3707,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { __ ldr(string, MemOperand(element, kPointerSize, PostIndex)); __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset)); __ SmiUntag(string_length); - __ add(string, - string, - Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); + __ add(string, string, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); __ CopyBytes(string, result_pos, string_length, scratch1); __ cmp(element, elements_end); __ b(lt, &empty_separator_loop); // End while (element < elements_end). @@ -3754,7 +3717,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { // One-character separator case __ bind(&one_char_separator); // Replace separator with its ASCII character value. - __ ldrb(separator, FieldMemOperand(separator, SeqOneByteString::kHeaderSize)); + __ ldrb(separator, FieldMemOperand(separator, SeqAsciiString::kHeaderSize)); // Jump into the loop after the code that copies the separator, so the first // element is not preceded by a separator __ jmp(&one_char_separator_loop_entry); @@ -3774,9 +3737,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { __ ldr(string, MemOperand(element, kPointerSize, PostIndex)); __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset)); __ SmiUntag(string_length); - __ add(string, - string, - Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); + __ add(string, string, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); __ CopyBytes(string, result_pos, string_length, scratch1); __ cmp(element, elements_end); __ b(lt, &one_char_separator_loop); // End while (element < elements_end). @@ -3797,16 +3758,14 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { __ SmiUntag(string_length); __ add(string, separator, - Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); + Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); __ CopyBytes(string, result_pos, string_length, scratch1); __ bind(&long_separator); __ ldr(string, MemOperand(element, kPointerSize, PostIndex)); __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset)); __ SmiUntag(string_length); - __ add(string, - string, - Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); + __ add(string, string, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); __ CopyBytes(string, result_pos, string_length, scratch1); __ cmp(element, elements_end); __ b(lt, &long_separator_loop); // End while (element < elements_end). @@ -4111,8 +4070,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // Call stub. Undo operation first. __ sub(r0, r0, Operand(Smi::FromInt(count_value))); } - __ mov(r1, r0); - __ mov(r0, Operand(Smi::FromInt(count_value))); + __ mov(r1, Operand(Smi::FromInt(count_value))); // Record position before stub call. SetSourcePosition(expr->position()); @@ -4337,7 +4295,29 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { default: { VisitForAccumulatorValue(expr->right()); - Condition cond = CompareIC::ComputeCondition(op); + Condition cond = eq; + switch (op) { + case Token::EQ_STRICT: + case Token::EQ: + cond = eq; + break; + case Token::LT: + cond = lt; + break; + case Token::GT: + cond = gt; + break; + case Token::LTE: + cond = le; + break; + case Token::GTE: + cond = ge; + break; + case Token::IN: + case Token::INSTANCEOF: + default: + UNREACHABLE(); + } __ pop(r1); bool inline_smi_code = ShouldInlineSmiCase(op); |