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 |