diff options
author | isaacs <i@izs.me> | 2012-06-09 08:09:42 -0700 |
---|---|---|
committer | isaacs <i@izs.me> | 2012-06-09 08:09:42 -0700 |
commit | 940a6863ead6622e5439e07be631359c31e63b68 (patch) | |
tree | c5aa25c048b8f0fd622d4c42fa134ca645fcbcd7 /deps/v8/src/arm/lithium-codegen-arm.cc | |
parent | 569acea0eefed2c7da7453b7dcef6ff47491ca1c (diff) | |
download | node-new-940a6863ead6622e5439e07be631359c31e63b68.tar.gz |
Roll V8 back to 3.9.24.31
Diffstat (limited to 'deps/v8/src/arm/lithium-codegen-arm.cc')
-rw-r--r-- | deps/v8/src/arm/lithium-codegen-arm.cc | 264 |
1 files changed, 41 insertions, 223 deletions
diff --git a/deps/v8/src/arm/lithium-codegen-arm.cc b/deps/v8/src/arm/lithium-codegen-arm.cc index 79b56fc077..82b80a2b80 100644 --- a/deps/v8/src/arm/lithium-codegen-arm.cc +++ b/deps/v8/src/arm/lithium-codegen-arm.cc @@ -1034,100 +1034,6 @@ void LCodeGen::DoModI(LModI* instr) { } -void LCodeGen::EmitSignedIntegerDivisionByConstant( - Register result, - Register dividend, - int32_t divisor, - Register remainder, - Register scratch, - LEnvironment* environment) { - ASSERT(!AreAliased(dividend, scratch, ip)); - ASSERT(LChunkBuilder::HasMagicNumberForDivisor(divisor)); - - uint32_t divisor_abs = abs(divisor); - - int32_t power_of_2_factor = - CompilerIntrinsics::CountTrailingZeros(divisor_abs); - - switch (divisor_abs) { - case 0: - DeoptimizeIf(al, environment); - return; - - case 1: - if (divisor > 0) { - __ Move(result, dividend); - } else { - __ rsb(result, dividend, Operand(0), SetCC); - DeoptimizeIf(vs, environment); - } - // Compute the remainder. - __ mov(remainder, Operand(0)); - return; - - default: - if (IsPowerOf2(divisor_abs)) { - // Branch and condition free code for integer division by a power - // of two. - int32_t power = WhichPowerOf2(divisor_abs); - if (power > 1) { - __ mov(scratch, Operand(dividend, ASR, power - 1)); - } - __ add(scratch, dividend, Operand(scratch, LSR, 32 - power)); - __ mov(result, Operand(scratch, ASR, power)); - // Negate if necessary. - // We don't need to check for overflow because the case '-1' is - // handled separately. - if (divisor < 0) { - ASSERT(divisor != -1); - __ rsb(result, result, Operand(0)); - } - // Compute the remainder. - if (divisor > 0) { - __ sub(remainder, dividend, Operand(result, LSL, power)); - } else { - __ add(remainder, dividend, Operand(result, LSL, power)); - } - return; - } else { - // Use magic numbers for a few specific divisors. - // Details and proofs can be found in: - // - Hacker's Delight, Henry S. Warren, Jr. - // - The PowerPC Compiler Writer’s Guide - // and probably many others. - // - // We handle - // <divisor with magic numbers> * <power of 2> - // but not - // <divisor with magic numbers> * <other divisor with magic numbers> - DivMagicNumbers magic_numbers = - DivMagicNumberFor(divisor_abs >> power_of_2_factor); - // Branch and condition free code for integer division by a power - // of two. - const int32_t M = magic_numbers.M; - const int32_t s = magic_numbers.s + power_of_2_factor; - - __ mov(ip, Operand(M)); - __ smull(ip, scratch, dividend, ip); - if (M < 0) { - __ add(scratch, scratch, Operand(dividend)); - } - if (s > 0) { - __ mov(scratch, Operand(scratch, ASR, s)); - } - __ add(result, scratch, Operand(dividend, LSR, 31)); - if (divisor < 0) __ rsb(result, result, Operand(0)); - // Compute the remainder. - __ mov(ip, Operand(divisor)); - // This sequence could be replaced with 'mls' when - // it gets implemented. - __ mul(scratch, result, ip); - __ sub(remainder, dividend, scratch); - } - } -} - - void LCodeGen::DoDivI(LDivI* instr) { class DeferredDivI: public LDeferredCode { public: @@ -1209,34 +1115,6 @@ void LCodeGen::DoDivI(LDivI* instr) { } -void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { - const Register result = ToRegister(instr->result()); - const Register left = ToRegister(instr->InputAt(0)); - const Register remainder = ToRegister(instr->TempAt(0)); - const Register scratch = scratch0(); - - // We only optimize this for division by constants, because the standard - // integer division routine is usually slower than transitionning to VFP. - // This could be optimized on processors with SDIV available. - ASSERT(instr->InputAt(1)->IsConstantOperand()); - int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1))); - if (divisor < 0) { - __ cmp(left, Operand(0)); - DeoptimizeIf(eq, instr->environment()); - } - EmitSignedIntegerDivisionByConstant(result, - left, - divisor, - remainder, - scratch, - instr->environment()); - // We operated a truncating division. Correct the result if necessary. - __ cmp(remainder, Operand(0)); - __ teq(remainder, Operand(divisor), ne); - __ sub(result, result, Operand(1), LeaveCC, mi); -} - - template<int T> void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr, Token::Value op) { @@ -2389,7 +2267,8 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, RelocInfo::CODE_TARGET, instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); - LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); + ASSERT(instr->HasDeoptimizationEnvironment()); + LEnvironment* env = instr->deoptimization_environment(); safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); // Put the result value into the result register slot and // restore all registers. @@ -2885,20 +2764,16 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { Register scratch = scratch0(); Register result = ToRegister(instr->result()); - if (instr->hydrogen()->from_inlined()) { - __ sub(result, sp, Operand(2 * kPointerSize)); - } else { - // Check if the calling frame is an arguments adaptor frame. - Label done, adapted; - __ ldr(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); - __ ldr(result, MemOperand(scratch, StandardFrameConstants::kContextOffset)); - __ cmp(result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); + // Check if the calling frame is an arguments adaptor frame. + Label done, adapted; + __ ldr(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); + __ ldr(result, MemOperand(scratch, StandardFrameConstants::kContextOffset)); + __ cmp(result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); - // Result is the frame pointer for the frame if not adapted and for the real - // frame below the adaptor frame if adapted. - __ mov(result, fp, LeaveCC, ne); - __ mov(result, scratch, LeaveCC, eq); - } + // Result is the frame pointer for the frame if not adapted and for the real + // frame below the adaptor frame if adapted. + __ mov(result, fp, LeaveCC, ne); + __ mov(result, scratch, LeaveCC, eq); } @@ -3007,7 +2882,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { __ b(ne, &loop); __ bind(&invoke); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); SafepointGenerator safepoint_generator( @@ -3032,11 +2907,6 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) { } -void LCodeGen::DoDrop(LDrop* instr) { - __ Drop(instr->count()); -} - - void LCodeGen::DoThisFunction(LThisFunction* instr) { Register result = ToRegister(instr->result()); __ LoadHeapObject(result, instr->hydrogen()->closure()); @@ -3083,8 +2953,7 @@ void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { void LCodeGen::CallKnownFunction(Handle<JSFunction> function, int arity, LInstruction* instr, - CallKind call_kind, - R1State r1_state) { + CallKind call_kind) { bool can_invoke_directly = !function->NeedsArgumentsAdaption() || function->shared()->formal_parameter_count() == arity; @@ -3092,10 +2961,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, RecordPosition(pointers->position()); if (can_invoke_directly) { - if (r1_state == R1_UNINITIALIZED) { - __ LoadHeapObject(r1, function); - } - + __ LoadHeapObject(r1, function); // Change context if needed. bool change_context = (info()->closure()->context() != function->context()) || @@ -3134,8 +3000,7 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { CallKnownFunction(instr->function(), instr->arity(), instr, - CALL_AS_METHOD, - R1_UNINITIALIZED); + CALL_AS_METHOD); } @@ -3559,21 +3424,13 @@ void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { ASSERT(ToRegister(instr->function()).is(r1)); ASSERT(instr->HasPointerMap()); - - if (instr->known_function().is_null()) { - LPointerMap* pointers = instr->pointer_map(); - RecordPosition(pointers->position()); - SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); - ParameterCount count(instr->arity()); - __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); - __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); - } else { - CallKnownFunction(instr->known_function(), - instr->arity(), - instr, - CALL_AS_METHOD, - R1_CONTAINS_TARGET); - } + ASSERT(instr->HasDeoptimizationEnvironment()); + LPointerMap* pointers = instr->pointer_map(); + RecordPosition(pointers->position()); + SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); + ParameterCount count(instr->arity()); + __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); + __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); } @@ -3628,11 +3485,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { ASSERT(ToRegister(instr->result()).is(r0)); - CallKnownFunction(instr->target(), - instr->arity(), - instr, - CALL_AS_FUNCTION, - R1_UNINITIALIZED); + CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); } @@ -3762,6 +3615,7 @@ void LCodeGen::DoStoreKeyedFastDoubleElement( Register scratch = scratch0(); bool key_is_constant = instr->key()->IsConstantOperand(); int constant_key = 0; + Label not_nan; // Calculate the effective address of the slot in the array to store the // double value. @@ -3784,15 +3638,13 @@ void LCodeGen::DoStoreKeyedFastDoubleElement( Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); } - if (instr->NeedsCanonicalization()) { - // Check for NaN. All NaNs must be canonicalized. - __ VFPCompareAndSetFlags(value, value); - // Only load canonical NaN if the comparison above set the overflow. - __ Vmov(value, - FixedDoubleArray::canonical_not_the_hole_nan_as_double(), - vs); - } + // Check for NaN. All NaNs must be canonicalized. + __ VFPCompareAndSetFlags(value, value); + + // Only load canonical NaN if the comparison above set the overflow. + __ Vmov(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double(), vs); + __ bind(¬_nan); __ vstr(value, scratch, 0); } @@ -4486,22 +4338,14 @@ void LCodeGen::DoCheckMapCommon(Register reg, } -void LCodeGen::DoCheckMaps(LCheckMaps* instr) { +void LCodeGen::DoCheckMap(LCheckMap* instr) { Register scratch = scratch0(); LOperand* input = instr->InputAt(0); ASSERT(input->IsRegister()); Register reg = ToRegister(input); - - Label success; - SmallMapList* map_set = instr->hydrogen()->map_set(); - for (int i = 0; i < map_set->length() - 1; i++) { - Handle<Map> map = map_set->at(i); - __ CompareMap(reg, scratch, map, &success, REQUIRE_EXACT_MAP); - __ b(eq, &success); - } - Handle<Map> map = map_set->last(); - DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP, instr->environment()); - __ bind(&success); + Handle<Map> map = instr->hydrogen()->map(); + DoCheckMapCommon(reg, scratch, map, instr->hydrogen()->mode(), + instr->environment()); } @@ -4620,14 +4464,6 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) { deferred->entry(), TAG_OBJECT); - __ bind(deferred->exit()); - if (FLAG_debug_code) { - Label is_in_new_space; - __ JumpIfInNewSpace(result, scratch, &is_in_new_space); - __ Abort("Allocated object is not in new-space"); - __ bind(&is_in_new_space); - } - // Load the initial map. Register map = scratch; __ LoadHeapObject(map, constructor); @@ -4646,14 +4482,14 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) { __ str(scratch, FieldMemOperand(result, property_offset)); } } + + __ bind(deferred->exit()); } void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { Register result = ToRegister(instr->result()); Handle<JSFunction> constructor = instr->hydrogen()->constructor(); - Handle<Map> initial_map(constructor->initial_map()); - int instance_size = initial_map->instance_size(); // TODO(3095996): Get rid of this. For now, we need to make the // result register contain a valid pointer because it is already @@ -4661,9 +4497,9 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { __ mov(result, Operand(0)); PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); - __ mov(r0, Operand(Smi::FromInt(instance_size))); + __ LoadHeapObject(r0, constructor); __ push(r0); - CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); + CallRuntimeFromDeferred(Runtime::kNewObject, 1, instr); __ StoreToSafepointRegisterSlot(r0, result); } @@ -4797,10 +4633,9 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, __ str(r2, FieldMemOperand(result, total_offset + 4)); } } else if (elements->IsFixedArray()) { - Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); for (int i = 0; i < elements_length; i++) { int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); - Handle<Object> value(fast_elements->get(i)); + Handle<Object> value = JSObject::GetElement(object, i); if (value->IsJSObject()) { Handle<JSObject> value_object = Handle<JSObject>::cast(value); __ add(r2, result, Operand(*offset)); @@ -4824,23 +4659,6 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, void LCodeGen::DoFastLiteral(LFastLiteral* instr) { int size = instr->hydrogen()->total_size(); - ElementsKind boilerplate_elements_kind = - instr->hydrogen()->boilerplate()->GetElementsKind(); - - // Deopt if the literal boilerplate ElementsKind is of a type different than - // the expected one. The check isn't necessary if the boilerplate has already - // been converted to FAST_ELEMENTS. - if (boilerplate_elements_kind != FAST_ELEMENTS) { - __ LoadHeapObject(r1, instr->hydrogen()->boilerplate()); - // Load map into r2. - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); - // Load the map's "bit field 2". - __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset)); - // Retrieve elements_kind from bit field 2. - __ ubfx(r2, r2, Map::kElementsKindShift, Map::kElementsKindBitCount); - __ cmp(r2, Operand(boilerplate_elements_kind)); - DeoptimizeIf(ne, instr->environment()); - } // Allocate all objects that are part of the literal in one big // allocation. This avoids multiple limit checks. @@ -5136,7 +4954,7 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { Register strict = scratch0(); __ mov(strict, Operand(Smi::FromInt(strict_mode_flag()))); __ Push(object, key, strict); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); SafepointGenerator safepoint_generator( @@ -5149,7 +4967,7 @@ void LCodeGen::DoIn(LIn* instr) { Register obj = ToRegister(instr->object()); Register key = ToRegister(instr->key()); __ Push(key, obj); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt); |