| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1204 __ xorps(res, res); | 1204 __ xorps(res, res); |
| 1205 } else { | 1205 } else { |
| 1206 Register tmp = ToRegister(instr->TempAt(0)); | 1206 Register tmp = ToRegister(instr->TempAt(0)); |
| 1207 __ Set(tmp, int_val); | 1207 __ Set(tmp, int_val); |
| 1208 __ movq(res, tmp); | 1208 __ movq(res, tmp); |
| 1209 } | 1209 } |
| 1210 } | 1210 } |
| 1211 | 1211 |
| 1212 | 1212 |
| 1213 void LCodeGen::DoConstantT(LConstantT* instr) { | 1213 void LCodeGen::DoConstantT(LConstantT* instr) { |
| 1214 ASSERT(instr->result()->IsRegister()); | 1214 Handle<Object> value = instr->value(); |
| 1215 __ Move(ToRegister(instr->result()), instr->value()); | 1215 if (value->IsSmi()) { |
| 1216 __ Move(ToRegister(instr->result()), value); |
| 1217 } else { |
| 1218 __ LoadHeapObject(ToRegister(instr->result()), |
| 1219 Handle<HeapObject>::cast(value)); |
| 1220 } |
| 1216 } | 1221 } |
| 1217 | 1222 |
| 1218 | 1223 |
| 1219 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { | 1224 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { |
| 1220 Register result = ToRegister(instr->result()); | 1225 Register result = ToRegister(instr->result()); |
| 1221 Register array = ToRegister(instr->InputAt(0)); | 1226 Register array = ToRegister(instr->InputAt(0)); |
| 1222 __ movq(result, FieldOperand(array, JSArray::kLengthOffset)); | 1227 __ movq(result, FieldOperand(array, JSArray::kLengthOffset)); |
| 1223 } | 1228 } |
| 1224 | 1229 |
| 1225 | 1230 |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2001 __ CallRuntime(Runtime::kTraceExit, 1); | 2006 __ CallRuntime(Runtime::kTraceExit, 1); |
| 2002 } | 2007 } |
| 2003 __ movq(rsp, rbp); | 2008 __ movq(rsp, rbp); |
| 2004 __ pop(rbp); | 2009 __ pop(rbp); |
| 2005 __ Ret((GetParameterCount() + 1) * kPointerSize, rcx); | 2010 __ Ret((GetParameterCount() + 1) * kPointerSize, rcx); |
| 2006 } | 2011 } |
| 2007 | 2012 |
| 2008 | 2013 |
| 2009 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { | 2014 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { |
| 2010 Register result = ToRegister(instr->result()); | 2015 Register result = ToRegister(instr->result()); |
| 2011 if (result.is(rax)) { | 2016 __ LoadGlobalCell(result, instr->hydrogen()->cell()); |
| 2012 __ load_rax(instr->hydrogen()->cell().location(), | |
| 2013 RelocInfo::GLOBAL_PROPERTY_CELL); | |
| 2014 } else { | |
| 2015 __ movq(result, instr->hydrogen()->cell(), RelocInfo::GLOBAL_PROPERTY_CELL); | |
| 2016 __ movq(result, Operand(result, 0)); | |
| 2017 } | |
| 2018 if (instr->hydrogen()->RequiresHoleCheck()) { | 2017 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 2019 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 2018 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
| 2020 DeoptimizeIf(equal, instr->environment()); | 2019 DeoptimizeIf(equal, instr->environment()); |
| 2021 } | 2020 } |
| 2022 } | 2021 } |
| 2023 | 2022 |
| 2024 | 2023 |
| 2025 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 2024 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
| 2026 ASSERT(ToRegister(instr->global_object()).is(rax)); | 2025 ASSERT(ToRegister(instr->global_object()).is(rax)); |
| 2027 ASSERT(ToRegister(instr->result()).is(rax)); | 2026 ASSERT(ToRegister(instr->result()).is(rax)); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2129 // Negative property indices are in-object properties, indexed | 2128 // Negative property indices are in-object properties, indexed |
| 2130 // from the end of the fixed part of the object. | 2129 // from the end of the fixed part of the object. |
| 2131 __ movq(result, FieldOperand(object, offset + type->instance_size())); | 2130 __ movq(result, FieldOperand(object, offset + type->instance_size())); |
| 2132 } else { | 2131 } else { |
| 2133 // Non-negative property indices are in the properties array. | 2132 // Non-negative property indices are in the properties array. |
| 2134 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); | 2133 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); |
| 2135 __ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize)); | 2134 __ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize)); |
| 2136 } | 2135 } |
| 2137 } else { | 2136 } else { |
| 2138 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type)); | 2137 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type)); |
| 2139 LoadHeapObject(result, Handle<HeapObject>::cast(function)); | 2138 __ LoadHeapObject(result, function); |
| 2140 } | 2139 } |
| 2141 } | 2140 } |
| 2142 | 2141 |
| 2143 | 2142 |
| 2144 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { | 2143 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { |
| 2145 Register object = ToRegister(instr->object()); | 2144 Register object = ToRegister(instr->object()); |
| 2146 Register result = ToRegister(instr->result()); | 2145 Register result = ToRegister(instr->result()); |
| 2147 | 2146 |
| 2148 int map_count = instr->hydrogen()->types()->length(); | 2147 int map_count = instr->hydrogen()->types()->length(); |
| 2149 Handle<String> name = instr->hydrogen()->name(); | 2148 Handle<String> name = instr->hydrogen()->name(); |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2625 // Setup deoptimization. | 2624 // Setup deoptimization. |
| 2626 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT, 0); | 2625 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT, 0); |
| 2627 | 2626 |
| 2628 // Restore context. | 2627 // Restore context. |
| 2629 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2628 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 2630 } | 2629 } |
| 2631 | 2630 |
| 2632 | 2631 |
| 2633 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 2632 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
| 2634 ASSERT(ToRegister(instr->result()).is(rax)); | 2633 ASSERT(ToRegister(instr->result()).is(rax)); |
| 2635 __ Move(rdi, instr->function()); | 2634 __ LoadHeapObject(rdi, instr->function()); |
| 2636 CallKnownFunction(instr->function(), | 2635 CallKnownFunction(instr->function(), |
| 2637 instr->arity(), | 2636 instr->arity(), |
| 2638 instr, | 2637 instr, |
| 2639 CALL_AS_METHOD); | 2638 CALL_AS_METHOD); |
| 2640 } | 2639 } |
| 2641 | 2640 |
| 2642 | 2641 |
| 2643 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 2642 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { |
| 2644 Register input_reg = ToRegister(instr->InputAt(0)); | 2643 Register input_reg = ToRegister(instr->InputAt(0)); |
| 2645 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), | 2644 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3024 Handle<Code> ic = | 3023 Handle<Code> ic = |
| 3025 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); | 3024 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); |
| 3026 __ Move(rcx, instr->name()); | 3025 __ Move(rcx, instr->name()); |
| 3027 CallCode(ic, mode, instr); | 3026 CallCode(ic, mode, instr); |
| 3028 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 3027 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 3029 } | 3028 } |
| 3030 | 3029 |
| 3031 | 3030 |
| 3032 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 3031 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
| 3033 ASSERT(ToRegister(instr->result()).is(rax)); | 3032 ASSERT(ToRegister(instr->result()).is(rax)); |
| 3034 __ Move(rdi, instr->target()); | 3033 __ LoadHeapObject(rdi, instr->target()); |
| 3035 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); | 3034 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); |
| 3036 } | 3035 } |
| 3037 | 3036 |
| 3038 | 3037 |
| 3039 void LCodeGen::DoCallNew(LCallNew* instr) { | 3038 void LCodeGen::DoCallNew(LCallNew* instr) { |
| 3040 ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); | 3039 ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); |
| 3041 ASSERT(ToRegister(instr->result()).is(rax)); | 3040 ASSERT(ToRegister(instr->result()).is(rax)); |
| 3042 | 3041 |
| 3043 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); | 3042 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); |
| 3044 __ Set(rax, instr->arity()); | 3043 __ Set(rax, instr->arity()); |
| (...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3710 FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); | 3709 FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); |
| 3711 __ andb(kScratchRegister, Immediate(mask)); | 3710 __ andb(kScratchRegister, Immediate(mask)); |
| 3712 __ cmpb(kScratchRegister, Immediate(tag)); | 3711 __ cmpb(kScratchRegister, Immediate(tag)); |
| 3713 DeoptimizeIf(not_equal, instr->environment()); | 3712 DeoptimizeIf(not_equal, instr->environment()); |
| 3714 } | 3713 } |
| 3715 } | 3714 } |
| 3716 } | 3715 } |
| 3717 | 3716 |
| 3718 | 3717 |
| 3719 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { | 3718 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { |
| 3720 ASSERT(instr->InputAt(0)->IsRegister()); | 3719 Register reg = ToRegister(instr->value()); |
| 3721 Register reg = ToRegister(instr->InputAt(0)); | 3720 Handle<JSFunction> target = instr->hydrogen()->target(); |
| 3722 __ Cmp(reg, instr->hydrogen()->target()); | 3721 if (isolate()->heap()->InNewSpace(*target)) { |
| 3722 Handle<JSGlobalPropertyCell> cell = |
| 3723 isolate()->factory()->NewJSGlobalPropertyCell(target); |
| 3724 __ movq(kScratchRegister, cell, RelocInfo::GLOBAL_PROPERTY_CELL); |
| 3725 __ cmpq(reg, Operand(kScratchRegister, 0)); |
| 3726 } else { |
| 3727 __ Cmp(reg, target); |
| 3728 } |
| 3723 DeoptimizeIf(not_equal, instr->environment()); | 3729 DeoptimizeIf(not_equal, instr->environment()); |
| 3724 } | 3730 } |
| 3725 | 3731 |
| 3726 | 3732 |
| 3727 void LCodeGen::DoCheckMap(LCheckMap* instr) { | 3733 void LCodeGen::DoCheckMap(LCheckMap* instr) { |
| 3728 LOperand* input = instr->InputAt(0); | 3734 LOperand* input = instr->InputAt(0); |
| 3729 ASSERT(input->IsRegister()); | 3735 ASSERT(input->IsRegister()); |
| 3730 Register reg = ToRegister(input); | 3736 Register reg = ToRegister(input); |
| 3731 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), | 3737 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 3732 instr->hydrogen()->map()); | 3738 instr->hydrogen()->map()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3778 | 3784 |
| 3779 // smi | 3785 // smi |
| 3780 __ bind(&is_smi); | 3786 __ bind(&is_smi); |
| 3781 __ SmiToInteger32(input_reg, input_reg); | 3787 __ SmiToInteger32(input_reg, input_reg); |
| 3782 __ ClampUint8(input_reg); | 3788 __ ClampUint8(input_reg); |
| 3783 | 3789 |
| 3784 __ bind(&done); | 3790 __ bind(&done); |
| 3785 } | 3791 } |
| 3786 | 3792 |
| 3787 | 3793 |
| 3788 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) { | |
| 3789 if (heap()->InNewSpace(*object)) { | |
| 3790 Handle<JSGlobalPropertyCell> cell = | |
| 3791 factory()->NewJSGlobalPropertyCell(object); | |
| 3792 __ movq(result, cell, RelocInfo::GLOBAL_PROPERTY_CELL); | |
| 3793 __ movq(result, Operand(result, 0)); | |
| 3794 } else { | |
| 3795 __ Move(result, object); | |
| 3796 } | |
| 3797 } | |
| 3798 | |
| 3799 | |
| 3800 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { | 3794 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { |
| 3801 Register reg = ToRegister(instr->TempAt(0)); | 3795 Register reg = ToRegister(instr->TempAt(0)); |
| 3802 | 3796 |
| 3803 Handle<JSObject> holder = instr->holder(); | 3797 Handle<JSObject> holder = instr->holder(); |
| 3804 Handle<JSObject> current_prototype = instr->prototype(); | 3798 Handle<JSObject> current_prototype = instr->prototype(); |
| 3805 | 3799 |
| 3806 // Load prototype object. | 3800 // Load prototype object. |
| 3807 LoadHeapObject(reg, current_prototype); | 3801 __ LoadHeapObject(reg, current_prototype); |
| 3808 | 3802 |
| 3809 // Check prototype maps up to the holder. | 3803 // Check prototype maps up to the holder. |
| 3810 while (!current_prototype.is_identical_to(holder)) { | 3804 while (!current_prototype.is_identical_to(holder)) { |
| 3811 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), | 3805 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 3812 Handle<Map>(current_prototype->map())); | 3806 Handle<Map>(current_prototype->map())); |
| 3813 DeoptimizeIf(not_equal, instr->environment()); | 3807 DeoptimizeIf(not_equal, instr->environment()); |
| 3814 current_prototype = | 3808 current_prototype = |
| 3815 Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype())); | 3809 Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype())); |
| 3816 // Load next prototype object. | 3810 // Load next prototype object. |
| 3817 LoadHeapObject(reg, current_prototype); | 3811 __ LoadHeapObject(reg, current_prototype); |
| 3818 } | 3812 } |
| 3819 | 3813 |
| 3820 // Check the holder map. | 3814 // Check the holder map. |
| 3821 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), | 3815 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 3822 Handle<Map>(current_prototype->map())); | 3816 Handle<Map>(current_prototype->map())); |
| 3823 DeoptimizeIf(not_equal, instr->environment()); | 3817 DeoptimizeIf(not_equal, instr->environment()); |
| 3824 } | 3818 } |
| 3825 | 3819 |
| 3826 | 3820 |
| 3827 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 3821 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3952 void LCodeGen::DoTypeof(LTypeof* instr) { | 3946 void LCodeGen::DoTypeof(LTypeof* instr) { |
| 3953 LOperand* input = instr->InputAt(0); | 3947 LOperand* input = instr->InputAt(0); |
| 3954 EmitPushTaggedOperand(input); | 3948 EmitPushTaggedOperand(input); |
| 3955 CallRuntime(Runtime::kTypeof, 1, instr); | 3949 CallRuntime(Runtime::kTypeof, 1, instr); |
| 3956 } | 3950 } |
| 3957 | 3951 |
| 3958 | 3952 |
| 3959 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { | 3953 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { |
| 3960 ASSERT(!operand->IsDoubleRegister()); | 3954 ASSERT(!operand->IsDoubleRegister()); |
| 3961 if (operand->IsConstantOperand()) { | 3955 if (operand->IsConstantOperand()) { |
| 3962 __ Push(ToHandle(LConstantOperand::cast(operand))); | 3956 Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); |
| 3957 if (object->IsSmi()) { |
| 3958 __ Push(Handle<Smi>::cast(object)); |
| 3959 } else { |
| 3960 __ PushHeapObject(Handle<HeapObject>::cast(object)); |
| 3961 } |
| 3963 } else if (operand->IsRegister()) { | 3962 } else if (operand->IsRegister()) { |
| 3964 __ push(ToRegister(operand)); | 3963 __ push(ToRegister(operand)); |
| 3965 } else { | 3964 } else { |
| 3966 __ push(ToOperand(operand)); | 3965 __ push(ToOperand(operand)); |
| 3967 } | 3966 } |
| 3968 } | 3967 } |
| 3969 | 3968 |
| 3970 | 3969 |
| 3971 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 3970 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
| 3972 Register input = ToRegister(instr->InputAt(0)); | 3971 Register input = ToRegister(instr->InputAt(0)); |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4196 RegisterEnvironmentForDeoptimization(environment); | 4195 RegisterEnvironmentForDeoptimization(environment); |
| 4197 ASSERT(osr_pc_offset_ == -1); | 4196 ASSERT(osr_pc_offset_ == -1); |
| 4198 osr_pc_offset_ = masm()->pc_offset(); | 4197 osr_pc_offset_ = masm()->pc_offset(); |
| 4199 } | 4198 } |
| 4200 | 4199 |
| 4201 #undef __ | 4200 #undef __ |
| 4202 | 4201 |
| 4203 } } // namespace v8::internal | 4202 } } // namespace v8::internal |
| 4204 | 4203 |
| 4205 #endif // V8_TARGET_ARCH_X64 | 4204 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |