| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 GenerateDeferredCode() && | 77 GenerateDeferredCode() && |
| 78 GenerateDeoptJumpTable() && | 78 GenerateDeoptJumpTable() && |
| 79 GenerateSafepointTable(); | 79 GenerateSafepointTable(); |
| 80 } | 80 } |
| 81 | 81 |
| 82 | 82 |
| 83 void LCodeGen::FinishCode(Handle<Code> code) { | 83 void LCodeGen::FinishCode(Handle<Code> code) { |
| 84 ASSERT(is_done()); | 84 ASSERT(is_done()); |
| 85 code->set_stack_slots(GetStackSlotCount()); | 85 code->set_stack_slots(GetStackSlotCount()); |
| 86 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); | 86 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); |
| 87 if (FLAG_weak_embedded_maps_in_optimized_code) { | 87 RegisterDependentCodeForEmbeddedMaps(code); |
| 88 RegisterDependentCodeForEmbeddedMaps(code); | |
| 89 } | |
| 90 PopulateDeoptimizationData(code); | 88 PopulateDeoptimizationData(code); |
| 91 info()->CommitDependencies(code); | 89 info()->CommitDependencies(code); |
| 92 } | 90 } |
| 93 | 91 |
| 94 | 92 |
| 95 void LChunkBuilder::Abort(BailoutReason reason) { | 93 void LChunkBuilder::Abort(BailoutReason reason) { |
| 96 info()->set_bailout_reason(reason); | 94 info()->set_bailout_reason(reason); |
| 97 status_ = ABORTED; | 95 status_ = ABORTED; |
| 98 } | 96 } |
| 99 | 97 |
| (...skipping 740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 LEnvironment* environment, | 838 LEnvironment* environment, |
| 841 Register src1, | 839 Register src1, |
| 842 const Operand& src2) { | 840 const Operand& src2) { |
| 843 Deoptimizer::BailoutType bailout_type = info()->IsStub() | 841 Deoptimizer::BailoutType bailout_type = info()->IsStub() |
| 844 ? Deoptimizer::LAZY | 842 ? Deoptimizer::LAZY |
| 845 : Deoptimizer::EAGER; | 843 : Deoptimizer::EAGER; |
| 846 DeoptimizeIf(condition, environment, bailout_type, src1, src2); | 844 DeoptimizeIf(condition, environment, bailout_type, src1, src2); |
| 847 } | 845 } |
| 848 | 846 |
| 849 | 847 |
| 850 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) { | |
| 851 ZoneList<Handle<Map> > maps(1, zone()); | |
| 852 ZoneList<Handle<JSObject> > objects(1, zone()); | |
| 853 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | |
| 854 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { | |
| 855 if (Code::IsWeakEmbeddedObject(code->kind(), it.rinfo()->target_object())) { | |
| 856 if (it.rinfo()->target_object()->IsMap()) { | |
| 857 Handle<Map> map(Map::cast(it.rinfo()->target_object())); | |
| 858 maps.Add(map, zone()); | |
| 859 } else if (it.rinfo()->target_object()->IsJSObject()) { | |
| 860 Handle<JSObject> object(JSObject::cast(it.rinfo()->target_object())); | |
| 861 objects.Add(object, zone()); | |
| 862 } | |
| 863 } | |
| 864 } | |
| 865 #ifdef VERIFY_HEAP | |
| 866 // This disables verification of weak embedded objects after full GC. | |
| 867 // AddDependentCode can cause a GC, which would observe the state where | |
| 868 // this code is not yet in the depended code lists of the embedded maps. | |
| 869 NoWeakObjectVerificationScope disable_verification_of_embedded_objects; | |
| 870 #endif | |
| 871 for (int i = 0; i < maps.length(); i++) { | |
| 872 maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code); | |
| 873 } | |
| 874 for (int i = 0; i < objects.length(); i++) { | |
| 875 AddWeakObjectToCodeDependency(isolate()->heap(), objects.at(i), code); | |
| 876 } | |
| 877 } | |
| 878 | |
| 879 | |
| 880 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { | 848 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { |
| 881 int length = deoptimizations_.length(); | 849 int length = deoptimizations_.length(); |
| 882 if (length == 0) return; | 850 if (length == 0) return; |
| 883 Handle<DeoptimizationInputData> data = | 851 Handle<DeoptimizationInputData> data = |
| 884 factory()->NewDeoptimizationInputData(length, TENURED); | 852 factory()->NewDeoptimizationInputData(length, TENURED); |
| 885 | 853 |
| 886 Handle<ByteArray> translations = | 854 Handle<ByteArray> translations = |
| 887 translations_.CreateByteArray(isolate()->factory()); | 855 translations_.CreateByteArray(isolate()->factory()); |
| 888 data->SetTranslationByteArray(*translations); | 856 data->SetTranslationByteArray(*translations); |
| 889 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); | 857 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); |
| (...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1834 MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding); | 1802 MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding); |
| 1835 if (encoding == String::ONE_BYTE_ENCODING) { | 1803 if (encoding == String::ONE_BYTE_ENCODING) { |
| 1836 __ sb(value, operand); | 1804 __ sb(value, operand); |
| 1837 } else { | 1805 } else { |
| 1838 __ sh(value, operand); | 1806 __ sh(value, operand); |
| 1839 } | 1807 } |
| 1840 } | 1808 } |
| 1841 | 1809 |
| 1842 | 1810 |
| 1843 void LCodeGen::DoThrow(LThrow* instr) { | 1811 void LCodeGen::DoThrow(LThrow* instr) { |
| 1844 Register input_reg = EmitLoadRegister(instr->value(), at); | 1812 __ push(ToRegister(instr->value())); |
| 1845 __ push(input_reg); | |
| 1846 ASSERT(ToRegister(instr->context()).is(cp)); | 1813 ASSERT(ToRegister(instr->context()).is(cp)); |
| 1847 CallRuntime(Runtime::kThrow, 1, instr); | 1814 CallRuntime(Runtime::kThrow, 1, instr); |
| 1848 | 1815 |
| 1849 if (FLAG_debug_code) { | 1816 if (FLAG_debug_code) { |
| 1850 __ stop("Unreachable code."); | 1817 __ stop("Unreachable code."); |
| 1851 } | 1818 } |
| 1852 } | 1819 } |
| 1853 | 1820 |
| 1854 | 1821 |
| 1855 void LCodeGen::DoAddI(LAddI* instr) { | 1822 void LCodeGen::DoAddI(LAddI* instr) { |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1993 } | 1960 } |
| 1994 } | 1961 } |
| 1995 | 1962 |
| 1996 | 1963 |
| 1997 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { | 1964 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { |
| 1998 ASSERT(ToRegister(instr->context()).is(cp)); | 1965 ASSERT(ToRegister(instr->context()).is(cp)); |
| 1999 ASSERT(ToRegister(instr->left()).is(a1)); | 1966 ASSERT(ToRegister(instr->left()).is(a1)); |
| 2000 ASSERT(ToRegister(instr->right()).is(a0)); | 1967 ASSERT(ToRegister(instr->right()).is(a0)); |
| 2001 ASSERT(ToRegister(instr->result()).is(v0)); | 1968 ASSERT(ToRegister(instr->result()).is(v0)); |
| 2002 | 1969 |
| 2003 BinaryOpStub stub(instr->op(), NO_OVERWRITE); | 1970 BinaryOpICStub stub(instr->op(), NO_OVERWRITE); |
| 2004 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1971 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 2005 // Other arch use a nop here, to signal that there is no inlined | 1972 // Other arch use a nop here, to signal that there is no inlined |
| 2006 // patchable code. Mips does not need the nop, since our marker | 1973 // patchable code. Mips does not need the nop, since our marker |
| 2007 // instruction (andi zero_reg) will never be used in normal code. | 1974 // instruction (andi zero_reg) will never be used in normal code. |
| 2008 } | 1975 } |
| 2009 | 1976 |
| 2010 | 1977 |
| 2011 template<class InstrType> | 1978 template<class InstrType> |
| 2012 void LCodeGen::EmitBranch(InstrType instr, | 1979 void LCodeGen::EmitBranch(InstrType instr, |
| 2013 Condition condition, | 1980 Condition condition, |
| (...skipping 1352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3366 __ SmiUntag(result); | 3333 __ SmiUntag(result); |
| 3367 | 3334 |
| 3368 // Argument length is in result register. | 3335 // Argument length is in result register. |
| 3369 __ bind(&done); | 3336 __ bind(&done); |
| 3370 } | 3337 } |
| 3371 | 3338 |
| 3372 | 3339 |
| 3373 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { | 3340 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { |
| 3374 Register receiver = ToRegister(instr->receiver()); | 3341 Register receiver = ToRegister(instr->receiver()); |
| 3375 Register function = ToRegister(instr->function()); | 3342 Register function = ToRegister(instr->function()); |
| 3343 Register result = ToRegister(instr->result()); |
| 3376 Register scratch = scratch0(); | 3344 Register scratch = scratch0(); |
| 3377 | 3345 |
| 3378 // If the receiver is null or undefined, we have to pass the global | 3346 // If the receiver is null or undefined, we have to pass the global |
| 3379 // object as a receiver to normal functions. Values have to be | 3347 // object as a receiver to normal functions. Values have to be |
| 3380 // passed unchanged to builtins and strict-mode functions. | 3348 // passed unchanged to builtins and strict-mode functions. |
| 3381 Label global_object, receiver_ok; | 3349 Label global_object, result_in_receiver; |
| 3382 | 3350 |
| 3383 // Do not transform the receiver to object for strict mode | 3351 // Do not transform the receiver to object for strict mode |
| 3384 // functions. | 3352 // functions. |
| 3385 __ lw(scratch, | 3353 __ lw(scratch, |
| 3386 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); | 3354 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); |
| 3387 __ lw(scratch, | 3355 __ lw(scratch, |
| 3388 FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset)); | 3356 FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset)); |
| 3389 | 3357 |
| 3390 // Do not transform the receiver to object for builtins. | 3358 // Do not transform the receiver to object for builtins. |
| 3391 int32_t strict_mode_function_mask = | 3359 int32_t strict_mode_function_mask = |
| 3392 1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize); | 3360 1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize); |
| 3393 int32_t native_mask = 1 << (SharedFunctionInfo::kNative + kSmiTagSize); | 3361 int32_t native_mask = 1 << (SharedFunctionInfo::kNative + kSmiTagSize); |
| 3394 __ And(scratch, scratch, Operand(strict_mode_function_mask | native_mask)); | 3362 __ And(scratch, scratch, Operand(strict_mode_function_mask | native_mask)); |
| 3395 __ Branch(&receiver_ok, ne, scratch, Operand(zero_reg)); | 3363 __ Branch(&result_in_receiver, ne, scratch, Operand(zero_reg)); |
| 3396 | 3364 |
| 3397 // Normal function. Replace undefined or null with global receiver. | 3365 // Normal function. Replace undefined or null with global receiver. |
| 3398 __ LoadRoot(scratch, Heap::kNullValueRootIndex); | 3366 __ LoadRoot(scratch, Heap::kNullValueRootIndex); |
| 3399 __ Branch(&global_object, eq, receiver, Operand(scratch)); | 3367 __ Branch(&global_object, eq, receiver, Operand(scratch)); |
| 3400 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); | 3368 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); |
| 3401 __ Branch(&global_object, eq, receiver, Operand(scratch)); | 3369 __ Branch(&global_object, eq, receiver, Operand(scratch)); |
| 3402 | 3370 |
| 3403 // Deoptimize if the receiver is not a JS object. | 3371 // Deoptimize if the receiver is not a JS object. |
| 3404 __ SmiTst(receiver, scratch); | 3372 __ SmiTst(receiver, scratch); |
| 3405 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); | 3373 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); |
| 3406 | 3374 |
| 3407 __ GetObjectType(receiver, scratch, scratch); | 3375 __ GetObjectType(receiver, scratch, scratch); |
| 3408 DeoptimizeIf(lt, instr->environment(), | 3376 DeoptimizeIf(lt, instr->environment(), |
| 3409 scratch, Operand(FIRST_SPEC_OBJECT_TYPE)); | 3377 scratch, Operand(FIRST_SPEC_OBJECT_TYPE)); |
| 3410 __ Branch(&receiver_ok); | 3378 __ Branch(&result_in_receiver); |
| 3411 | 3379 |
| 3412 __ bind(&global_object); | 3380 __ bind(&global_object); |
| 3413 __ lw(receiver, GlobalObjectOperand()); | 3381 __ lw(result, GlobalObjectOperand()); |
| 3414 __ lw(receiver, | 3382 __ lw(result, |
| 3415 FieldMemOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); | 3383 FieldMemOperand(result, JSGlobalObject::kGlobalReceiverOffset)); |
| 3416 __ bind(&receiver_ok); | 3384 if (result.is(receiver)) { |
| 3385 __ bind(&result_in_receiver); |
| 3386 } else { |
| 3387 Label result_ok; |
| 3388 __ Branch(&result_ok); |
| 3389 __ bind(&result_in_receiver); |
| 3390 __ mov(result, receiver); |
| 3391 __ bind(&result_ok); |
| 3392 } |
| 3417 } | 3393 } |
| 3418 | 3394 |
| 3419 | 3395 |
| 3420 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { | 3396 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { |
| 3421 Register receiver = ToRegister(instr->receiver()); | 3397 Register receiver = ToRegister(instr->receiver()); |
| 3422 Register function = ToRegister(instr->function()); | 3398 Register function = ToRegister(instr->function()); |
| 3423 Register length = ToRegister(instr->length()); | 3399 Register length = ToRegister(instr->length()); |
| 3424 Register elements = ToRegister(instr->elements()); | 3400 Register elements = ToRegister(instr->elements()); |
| 3425 Register scratch = scratch0(); | 3401 Register scratch = scratch0(); |
| 3426 ASSERT(receiver.is(a0)); // Used for parameter count. | 3402 ASSERT(receiver.is(a0)); // Used for parameter count. |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3891 ASSERT(ToDoubleRegister(instr->result()).is(f4)); | 3867 ASSERT(ToDoubleRegister(instr->result()).is(f4)); |
| 3892 // Set the context register to a GC-safe fake value. Clobbering it is | 3868 // Set the context register to a GC-safe fake value. Clobbering it is |
| 3893 // OK because this instruction is marked as a call. | 3869 // OK because this instruction is marked as a call. |
| 3894 __ mov(cp, zero_reg); | 3870 __ mov(cp, zero_reg); |
| 3895 TranscendentalCacheStub stub(TranscendentalCache::LOG, | 3871 TranscendentalCacheStub stub(TranscendentalCache::LOG, |
| 3896 TranscendentalCacheStub::UNTAGGED); | 3872 TranscendentalCacheStub::UNTAGGED); |
| 3897 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 3873 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 3898 } | 3874 } |
| 3899 | 3875 |
| 3900 | 3876 |
| 3901 void LCodeGen::DoMathTan(LMathTan* instr) { | |
| 3902 ASSERT(ToDoubleRegister(instr->result()).is(f4)); | |
| 3903 // Set the context register to a GC-safe fake value. Clobbering it is | |
| 3904 // OK because this instruction is marked as a call. | |
| 3905 __ mov(cp, zero_reg); | |
| 3906 TranscendentalCacheStub stub(TranscendentalCache::TAN, | |
| 3907 TranscendentalCacheStub::UNTAGGED); | |
| 3908 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 3909 } | |
| 3910 | |
| 3911 | |
| 3912 void LCodeGen::DoMathCos(LMathCos* instr) { | |
| 3913 ASSERT(ToDoubleRegister(instr->result()).is(f4)); | |
| 3914 // Set the context register to a GC-safe fake value. Clobbering it is | |
| 3915 // OK because this instruction is marked as a call. | |
| 3916 __ mov(cp, zero_reg); | |
| 3917 TranscendentalCacheStub stub(TranscendentalCache::COS, | |
| 3918 TranscendentalCacheStub::UNTAGGED); | |
| 3919 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 3920 } | |
| 3921 | |
| 3922 | |
| 3923 void LCodeGen::DoMathSin(LMathSin* instr) { | |
| 3924 ASSERT(ToDoubleRegister(instr->result()).is(f4)); | |
| 3925 // Set the context register to a GC-safe fake value. Clobbering it is | |
| 3926 // OK because this instruction is marked as a call. | |
| 3927 __ mov(cp, zero_reg); | |
| 3928 TranscendentalCacheStub stub(TranscendentalCache::SIN, | |
| 3929 TranscendentalCacheStub::UNTAGGED); | |
| 3930 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 3931 } | |
| 3932 | |
| 3933 | |
| 3934 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 3877 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
| 3935 ASSERT(ToRegister(instr->context()).is(cp)); | 3878 ASSERT(ToRegister(instr->context()).is(cp)); |
| 3936 ASSERT(ToRegister(instr->function()).is(a1)); | 3879 ASSERT(ToRegister(instr->function()).is(a1)); |
| 3937 ASSERT(instr->HasPointerMap()); | 3880 ASSERT(instr->HasPointerMap()); |
| 3938 | 3881 |
| 3939 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); | 3882 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
| 3940 if (known_function.is_null()) { | 3883 if (known_function.is_null()) { |
| 3941 LPointerMap* pointers = instr->pointer_map(); | 3884 LPointerMap* pointers = instr->pointer_map(); |
| 3942 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3885 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 3943 ParameterCount count(instr->arity()); | 3886 ParameterCount count(instr->arity()); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4086 __ Addu(code_object, code_object, | 4029 __ Addu(code_object, code_object, |
| 4087 Operand(Code::kHeaderSize - kHeapObjectTag)); | 4030 Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 4088 __ sw(code_object, | 4031 __ sw(code_object, |
| 4089 FieldMemOperand(function, JSFunction::kCodeEntryOffset)); | 4032 FieldMemOperand(function, JSFunction::kCodeEntryOffset)); |
| 4090 } | 4033 } |
| 4091 | 4034 |
| 4092 | 4035 |
| 4093 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { | 4036 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { |
| 4094 Register result = ToRegister(instr->result()); | 4037 Register result = ToRegister(instr->result()); |
| 4095 Register base = ToRegister(instr->base_object()); | 4038 Register base = ToRegister(instr->base_object()); |
| 4096 __ Addu(result, base, Operand(instr->offset())); | 4039 if (instr->offset()->IsConstantOperand()) { |
| 4040 LConstantOperand* offset = LConstantOperand::cast(instr->offset()); |
| 4041 __ Addu(result, base, Operand(ToInteger32(offset))); |
| 4042 } else { |
| 4043 Register offset = ToRegister(instr->offset()); |
| 4044 __ Addu(result, base, offset); |
| 4045 } |
| 4097 } | 4046 } |
| 4098 | 4047 |
| 4099 | 4048 |
| 4100 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 4049 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
| 4101 Representation representation = instr->representation(); | 4050 Representation representation = instr->representation(); |
| 4102 | 4051 |
| 4103 Register object = ToRegister(instr->object()); | 4052 Register object = ToRegister(instr->object()); |
| 4104 Register scratch = scratch0(); | 4053 Register scratch = scratch0(); |
| 4105 HObjectAccess access = instr->hydrogen()->access(); | 4054 HObjectAccess access = instr->hydrogen()->access(); |
| 4106 int offset = access.offset(); | 4055 int offset = access.offset(); |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4701 virtual void Generate() V8_OVERRIDE { | 4650 virtual void Generate() V8_OVERRIDE { |
| 4702 codegen()->DoDeferredNumberTagI(instr_, | 4651 codegen()->DoDeferredNumberTagI(instr_, |
| 4703 instr_->value(), | 4652 instr_->value(), |
| 4704 UNSIGNED_INT32); | 4653 UNSIGNED_INT32); |
| 4705 } | 4654 } |
| 4706 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 4655 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
| 4707 private: | 4656 private: |
| 4708 LNumberTagU* instr_; | 4657 LNumberTagU* instr_; |
| 4709 }; | 4658 }; |
| 4710 | 4659 |
| 4711 LOperand* input = instr->value(); | 4660 Register input = ToRegister(instr->value()); |
| 4712 ASSERT(input->IsRegister() && input->Equals(instr->result())); | 4661 Register result = ToRegister(instr->result()); |
| 4713 Register reg = ToRegister(input); | |
| 4714 | 4662 |
| 4715 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); | 4663 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); |
| 4716 __ Branch(deferred->entry(), hi, reg, Operand(Smi::kMaxValue)); | 4664 __ Branch(deferred->entry(), hi, input, Operand(Smi::kMaxValue)); |
| 4717 __ SmiTag(reg, reg); | 4665 __ SmiTag(result, input); |
| 4718 __ bind(deferred->exit()); | 4666 __ bind(deferred->exit()); |
| 4719 } | 4667 } |
| 4720 | 4668 |
| 4721 | 4669 |
| 4722 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, | 4670 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, |
| 4723 LOperand* value, | 4671 LOperand* value, |
| 4724 IntegerSignedness signedness) { | 4672 IntegerSignedness signedness) { |
| 4725 Label slow; | 4673 Label slow; |
| 4726 Register src = ToRegister(value); | 4674 Register src = ToRegister(value); |
| 4727 Register dst = ToRegister(instr->result()); | 4675 Register dst = ToRegister(instr->result()); |
| (...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5870 __ Subu(scratch, result, scratch); | 5818 __ Subu(scratch, result, scratch); |
| 5871 __ lw(result, FieldMemOperand(scratch, | 5819 __ lw(result, FieldMemOperand(scratch, |
| 5872 FixedArray::kHeaderSize - kPointerSize)); | 5820 FixedArray::kHeaderSize - kPointerSize)); |
| 5873 __ bind(&done); | 5821 __ bind(&done); |
| 5874 } | 5822 } |
| 5875 | 5823 |
| 5876 | 5824 |
| 5877 #undef __ | 5825 #undef __ |
| 5878 | 5826 |
| 5879 } } // namespace v8::internal | 5827 } } // namespace v8::internal |
| OLD | NEW |