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 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1147 __ xorps(res, res); | 1147 __ xorps(res, res); |
1148 } else { | 1148 } else { |
1149 Register tmp = ToRegister(instr->TempAt(0)); | 1149 Register tmp = ToRegister(instr->TempAt(0)); |
1150 __ Set(tmp, int_val); | 1150 __ Set(tmp, int_val); |
1151 __ movq(res, tmp); | 1151 __ movq(res, tmp); |
1152 } | 1152 } |
1153 } | 1153 } |
1154 | 1154 |
1155 | 1155 |
1156 void LCodeGen::DoConstantT(LConstantT* instr) { | 1156 void LCodeGen::DoConstantT(LConstantT* instr) { |
1157 ASSERT(instr->result()->IsRegister()); | 1157 Handle<Object> value = instr->value(); |
1158 __ Move(ToRegister(instr->result()), instr->value()); | 1158 if (value->IsSmi()) { |
1159 __ Move(ToRegister(instr->result()), value); | |
1160 } else { | |
1161 __ LoadHeapObject(ToRegister(instr->result()), | |
1162 Handle<HeapObject>::cast(value)); | |
1163 } | |
1159 } | 1164 } |
1160 | 1165 |
1161 | 1166 |
1162 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { | 1167 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { |
1163 Register result = ToRegister(instr->result()); | 1168 Register result = ToRegister(instr->result()); |
1164 Register array = ToRegister(instr->InputAt(0)); | 1169 Register array = ToRegister(instr->InputAt(0)); |
1165 __ movq(result, FieldOperand(array, JSArray::kLengthOffset)); | 1170 __ movq(result, FieldOperand(array, JSArray::kLengthOffset)); |
1166 } | 1171 } |
1167 | 1172 |
1168 | 1173 |
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1925 | 1930 |
1926 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, | 1931 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, |
1927 Label* map_check) { | 1932 Label* map_check) { |
1928 { | 1933 { |
1929 PushSafepointRegistersScope scope(this); | 1934 PushSafepointRegistersScope scope(this); |
1930 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>( | 1935 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>( |
1931 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck); | 1936 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck); |
1932 InstanceofStub stub(flags); | 1937 InstanceofStub stub(flags); |
1933 | 1938 |
1934 __ push(ToRegister(instr->InputAt(0))); | 1939 __ push(ToRegister(instr->InputAt(0))); |
1935 __ Push(instr->function()); | 1940 __ PushHeapObject(instr->function()); |
fschneider
2011/12/01 14:33:17
Fixed missing PushHeapObject here.
| |
1936 | 1941 |
1937 static const int kAdditionalDelta = 10; | 1942 static const int kAdditionalDelta = 10; |
1938 int delta = | 1943 int delta = |
1939 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; | 1944 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; |
1940 ASSERT(delta >= 0); | 1945 ASSERT(delta >= 0); |
1941 __ push_imm32(delta); | 1946 __ push_imm32(delta); |
1942 | 1947 |
1943 // We are pushing three values on the stack but recording a | 1948 // We are pushing three values on the stack but recording a |
1944 // safepoint with two arguments because stub is going to | 1949 // safepoint with two arguments because stub is going to |
1945 // remove the third argument from the stack before jumping | 1950 // remove the third argument from the stack before jumping |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1995 __ CallRuntime(Runtime::kTraceExit, 1); | 2000 __ CallRuntime(Runtime::kTraceExit, 1); |
1996 } | 2001 } |
1997 __ movq(rsp, rbp); | 2002 __ movq(rsp, rbp); |
1998 __ pop(rbp); | 2003 __ pop(rbp); |
1999 __ Ret((GetParameterCount() + 1) * kPointerSize, rcx); | 2004 __ Ret((GetParameterCount() + 1) * kPointerSize, rcx); |
2000 } | 2005 } |
2001 | 2006 |
2002 | 2007 |
2003 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { | 2008 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { |
2004 Register result = ToRegister(instr->result()); | 2009 Register result = ToRegister(instr->result()); |
2005 if (result.is(rax)) { | 2010 __ LoadGlobalCell(result, instr->hydrogen()->cell()); |
2006 __ load_rax(instr->hydrogen()->cell().location(), | |
2007 RelocInfo::GLOBAL_PROPERTY_CELL); | |
2008 } else { | |
2009 __ movq(result, instr->hydrogen()->cell(), RelocInfo::GLOBAL_PROPERTY_CELL); | |
2010 __ movq(result, Operand(result, 0)); | |
2011 } | |
2012 if (instr->hydrogen()->RequiresHoleCheck()) { | 2011 if (instr->hydrogen()->RequiresHoleCheck()) { |
2013 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 2012 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
2014 DeoptimizeIf(equal, instr->environment()); | 2013 DeoptimizeIf(equal, instr->environment()); |
2015 } | 2014 } |
2016 } | 2015 } |
2017 | 2016 |
2018 | 2017 |
2019 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 2018 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
2020 ASSERT(ToRegister(instr->global_object()).is(rax)); | 2019 ASSERT(ToRegister(instr->global_object()).is(rax)); |
2021 ASSERT(ToRegister(instr->result()).is(rax)); | 2020 ASSERT(ToRegister(instr->result()).is(rax)); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2137 // Negative property indices are in-object properties, indexed | 2136 // Negative property indices are in-object properties, indexed |
2138 // from the end of the fixed part of the object. | 2137 // from the end of the fixed part of the object. |
2139 __ movq(result, FieldOperand(object, offset + type->instance_size())); | 2138 __ movq(result, FieldOperand(object, offset + type->instance_size())); |
2140 } else { | 2139 } else { |
2141 // Non-negative property indices are in the properties array. | 2140 // Non-negative property indices are in the properties array. |
2142 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); | 2141 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); |
2143 __ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize)); | 2142 __ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize)); |
2144 } | 2143 } |
2145 } else { | 2144 } else { |
2146 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type)); | 2145 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type)); |
2147 LoadHeapObject(result, Handle<HeapObject>::cast(function)); | 2146 __ LoadHeapObject(result, function); |
2148 } | 2147 } |
2149 } | 2148 } |
2150 | 2149 |
2151 | 2150 |
2152 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { | 2151 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { |
2153 Register object = ToRegister(instr->object()); | 2152 Register object = ToRegister(instr->object()); |
2154 Register result = ToRegister(instr->result()); | 2153 Register result = ToRegister(instr->result()); |
2155 | 2154 |
2156 int map_count = instr->hydrogen()->types()->length(); | 2155 int map_count = instr->hydrogen()->types()->length(); |
2157 Handle<String> name = instr->hydrogen()->name(); | 2156 Handle<String> name = instr->hydrogen()->name(); |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2559 | 2558 |
2560 | 2559 |
2561 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 2560 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
2562 LOperand* argument = instr->InputAt(0); | 2561 LOperand* argument = instr->InputAt(0); |
2563 EmitPushTaggedOperand(argument); | 2562 EmitPushTaggedOperand(argument); |
2564 } | 2563 } |
2565 | 2564 |
2566 | 2565 |
2567 void LCodeGen::DoThisFunction(LThisFunction* instr) { | 2566 void LCodeGen::DoThisFunction(LThisFunction* instr) { |
2568 Register result = ToRegister(instr->result()); | 2567 Register result = ToRegister(instr->result()); |
2569 LoadHeapObject(result, instr->hydrogen()->closure()); | 2568 __ LoadHeapObject(result, instr->hydrogen()->closure()); |
2570 } | 2569 } |
2571 | 2570 |
2572 | 2571 |
2573 void LCodeGen::DoContext(LContext* instr) { | 2572 void LCodeGen::DoContext(LContext* instr) { |
2574 Register result = ToRegister(instr->result()); | 2573 Register result = ToRegister(instr->result()); |
2575 __ movq(result, rsi); | 2574 __ movq(result, rsi); |
2576 } | 2575 } |
2577 | 2576 |
2578 | 2577 |
2579 void LCodeGen::DoOuterContext(LOuterContext* instr) { | 2578 void LCodeGen::DoOuterContext(LOuterContext* instr) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2630 // Setup deoptimization. | 2629 // Setup deoptimization. |
2631 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); | 2630 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); |
2632 | 2631 |
2633 // Restore context. | 2632 // Restore context. |
2634 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2633 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2635 } | 2634 } |
2636 | 2635 |
2637 | 2636 |
2638 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 2637 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
2639 ASSERT(ToRegister(instr->result()).is(rax)); | 2638 ASSERT(ToRegister(instr->result()).is(rax)); |
2640 __ Move(rdi, instr->function()); | 2639 __ LoadHeapObject(rdi, instr->function()); |
2641 CallKnownFunction(instr->function(), | 2640 CallKnownFunction(instr->function(), |
2642 instr->arity(), | 2641 instr->arity(), |
2643 instr, | 2642 instr, |
2644 CALL_AS_METHOD); | 2643 CALL_AS_METHOD); |
2645 } | 2644 } |
2646 | 2645 |
2647 | 2646 |
2648 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 2647 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { |
2649 Register input_reg = ToRegister(instr->InputAt(0)); | 2648 Register input_reg = ToRegister(instr->InputAt(0)); |
2650 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), | 2649 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3038 Handle<Code> ic = | 3037 Handle<Code> ic = |
3039 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); | 3038 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); |
3040 __ Move(rcx, instr->name()); | 3039 __ Move(rcx, instr->name()); |
3041 CallCode(ic, mode, instr); | 3040 CallCode(ic, mode, instr); |
3042 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 3041 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
3043 } | 3042 } |
3044 | 3043 |
3045 | 3044 |
3046 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 3045 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
3047 ASSERT(ToRegister(instr->result()).is(rax)); | 3046 ASSERT(ToRegister(instr->result()).is(rax)); |
3048 __ Move(rdi, instr->target()); | 3047 __ LoadHeapObject(rdi, instr->target()); |
3049 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); | 3048 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); |
3050 } | 3049 } |
3051 | 3050 |
3052 | 3051 |
3053 void LCodeGen::DoCallNew(LCallNew* instr) { | 3052 void LCodeGen::DoCallNew(LCallNew* instr) { |
3054 ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); | 3053 ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); |
3055 ASSERT(ToRegister(instr->result()).is(rax)); | 3054 ASSERT(ToRegister(instr->result()).is(rax)); |
3056 | 3055 |
3057 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); | 3056 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); |
3058 __ Set(rax, instr->arity()); | 3057 __ Set(rax, instr->arity()); |
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3721 FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); | 3720 FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); |
3722 __ andb(kScratchRegister, Immediate(mask)); | 3721 __ andb(kScratchRegister, Immediate(mask)); |
3723 __ cmpb(kScratchRegister, Immediate(tag)); | 3722 __ cmpb(kScratchRegister, Immediate(tag)); |
3724 DeoptimizeIf(not_equal, instr->environment()); | 3723 DeoptimizeIf(not_equal, instr->environment()); |
3725 } | 3724 } |
3726 } | 3725 } |
3727 } | 3726 } |
3728 | 3727 |
3729 | 3728 |
3730 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { | 3729 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { |
3731 ASSERT(instr->InputAt(0)->IsRegister()); | 3730 Register reg = ToRegister(instr->value()); |
3732 Register reg = ToRegister(instr->InputAt(0)); | 3731 Handle<JSFunction> target = instr->hydrogen()->target(); |
3733 __ Cmp(reg, instr->hydrogen()->target()); | 3732 if (isolate()->heap()->InNewSpace(*target)) { |
3733 Handle<JSGlobalPropertyCell> cell = | |
3734 isolate()->factory()->NewJSGlobalPropertyCell(target); | |
3735 __ movq(kScratchRegister, cell, RelocInfo::GLOBAL_PROPERTY_CELL); | |
3736 __ cmpq(reg, Operand(kScratchRegister, 0)); | |
3737 } else { | |
3738 __ Cmp(reg, target); | |
3739 } | |
3734 DeoptimizeIf(not_equal, instr->environment()); | 3740 DeoptimizeIf(not_equal, instr->environment()); |
3735 } | 3741 } |
3736 | 3742 |
3737 | 3743 |
3738 void LCodeGen::DoCheckMap(LCheckMap* instr) { | 3744 void LCodeGen::DoCheckMap(LCheckMap* instr) { |
3739 LOperand* input = instr->InputAt(0); | 3745 LOperand* input = instr->InputAt(0); |
3740 ASSERT(input->IsRegister()); | 3746 ASSERT(input->IsRegister()); |
3741 Register reg = ToRegister(input); | 3747 Register reg = ToRegister(input); |
3742 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), | 3748 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), |
3743 instr->hydrogen()->map()); | 3749 instr->hydrogen()->map()); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3789 | 3795 |
3790 // smi | 3796 // smi |
3791 __ bind(&is_smi); | 3797 __ bind(&is_smi); |
3792 __ SmiToInteger32(input_reg, input_reg); | 3798 __ SmiToInteger32(input_reg, input_reg); |
3793 __ ClampUint8(input_reg); | 3799 __ ClampUint8(input_reg); |
3794 | 3800 |
3795 __ bind(&done); | 3801 __ bind(&done); |
3796 } | 3802 } |
3797 | 3803 |
3798 | 3804 |
3799 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) { | |
3800 if (heap()->InNewSpace(*object)) { | |
3801 Handle<JSGlobalPropertyCell> cell = | |
3802 factory()->NewJSGlobalPropertyCell(object); | |
3803 __ movq(result, cell, RelocInfo::GLOBAL_PROPERTY_CELL); | |
3804 __ movq(result, Operand(result, 0)); | |
3805 } else { | |
3806 __ Move(result, object); | |
3807 } | |
3808 } | |
3809 | |
3810 | |
3811 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { | 3805 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { |
3812 Register reg = ToRegister(instr->TempAt(0)); | 3806 Register reg = ToRegister(instr->TempAt(0)); |
3813 | 3807 |
3814 Handle<JSObject> holder = instr->holder(); | 3808 Handle<JSObject> holder = instr->holder(); |
3815 Handle<JSObject> current_prototype = instr->prototype(); | 3809 Handle<JSObject> current_prototype = instr->prototype(); |
3816 | 3810 |
3817 // Load prototype object. | 3811 // Load prototype object. |
3818 LoadHeapObject(reg, current_prototype); | 3812 __ LoadHeapObject(reg, current_prototype); |
3819 | 3813 |
3820 // Check prototype maps up to the holder. | 3814 // Check prototype maps up to the holder. |
3821 while (!current_prototype.is_identical_to(holder)) { | 3815 while (!current_prototype.is_identical_to(holder)) { |
3822 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), | 3816 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), |
3823 Handle<Map>(current_prototype->map())); | 3817 Handle<Map>(current_prototype->map())); |
3824 DeoptimizeIf(not_equal, instr->environment()); | 3818 DeoptimizeIf(not_equal, instr->environment()); |
3825 current_prototype = | 3819 current_prototype = |
3826 Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype())); | 3820 Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype())); |
3827 // Load next prototype object. | 3821 // Load next prototype object. |
3828 LoadHeapObject(reg, current_prototype); | 3822 __ LoadHeapObject(reg, current_prototype); |
3829 } | 3823 } |
3830 | 3824 |
3831 // Check the holder map. | 3825 // Check the holder map. |
3832 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), | 3826 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), |
3833 Handle<Map>(current_prototype->map())); | 3827 Handle<Map>(current_prototype->map())); |
3834 DeoptimizeIf(not_equal, instr->environment()); | 3828 DeoptimizeIf(not_equal, instr->environment()); |
3835 } | 3829 } |
3836 | 3830 |
3837 | 3831 |
3838 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 3832 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3895 } | 3889 } |
3896 | 3890 |
3897 // Copy in-object properties. | 3891 // Copy in-object properties. |
3898 for (int i = 0; i < inobject_properties; i++) { | 3892 for (int i = 0; i < inobject_properties; i++) { |
3899 int total_offset = current_offset + object->GetInObjectPropertyOffset(i); | 3893 int total_offset = current_offset + object->GetInObjectPropertyOffset(i); |
3900 Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i)); | 3894 Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i)); |
3901 if (value->IsJSObject()) { | 3895 if (value->IsJSObject()) { |
3902 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 3896 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
3903 __ lea(rcx, Operand(result, *offset)); | 3897 __ lea(rcx, Operand(result, *offset)); |
3904 __ movq(FieldOperand(result, total_offset), rcx); | 3898 __ movq(FieldOperand(result, total_offset), rcx); |
3905 LoadHeapObject(source, value_object); | 3899 __ LoadHeapObject(source, value_object); |
3906 EmitDeepCopy(value_object, result, source, offset); | 3900 EmitDeepCopy(value_object, result, source, offset); |
3907 } else if (value->IsHeapObject()) { | 3901 } else if (value->IsHeapObject()) { |
3908 LoadHeapObject(rcx, Handle<HeapObject>::cast(value)); | 3902 __ LoadHeapObject(rcx, Handle<HeapObject>::cast(value)); |
3909 __ movq(FieldOperand(result, total_offset), rcx); | 3903 __ movq(FieldOperand(result, total_offset), rcx); |
3910 } else { | 3904 } else { |
3911 __ movq(rcx, value, RelocInfo::NONE); | 3905 __ movq(rcx, value, RelocInfo::NONE); |
3912 __ movq(FieldOperand(result, total_offset), rcx); | 3906 __ movq(FieldOperand(result, total_offset), rcx); |
3913 } | 3907 } |
3914 } | 3908 } |
3915 } | 3909 } |
3916 | 3910 |
3917 | 3911 |
3918 void LCodeGen::DoObjectLiteralFast(LObjectLiteralFast* instr) { | 3912 void LCodeGen::DoObjectLiteralFast(LObjectLiteralFast* instr) { |
3919 int size = instr->hydrogen()->total_size(); | 3913 int size = instr->hydrogen()->total_size(); |
3920 | 3914 |
3921 // Allocate all objects that are part of the literal in one big | 3915 // Allocate all objects that are part of the literal in one big |
3922 // allocation. This avoids multiple limit checks. | 3916 // allocation. This avoids multiple limit checks. |
3923 Label allocated, runtime_allocate; | 3917 Label allocated, runtime_allocate; |
3924 __ AllocateInNewSpace(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT); | 3918 __ AllocateInNewSpace(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT); |
3925 __ jmp(&allocated); | 3919 __ jmp(&allocated); |
3926 | 3920 |
3927 __ bind(&runtime_allocate); | 3921 __ bind(&runtime_allocate); |
3928 __ Push(Smi::FromInt(size)); | 3922 __ Push(Smi::FromInt(size)); |
3929 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); | 3923 CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); |
3930 | 3924 |
3931 __ bind(&allocated); | 3925 __ bind(&allocated); |
3932 int offset = 0; | 3926 int offset = 0; |
3933 LoadHeapObject(rbx, instr->hydrogen()->boilerplate()); | 3927 __ LoadHeapObject(rbx, instr->hydrogen()->boilerplate()); |
3934 EmitDeepCopy(instr->hydrogen()->boilerplate(), rax, rbx, &offset); | 3928 EmitDeepCopy(instr->hydrogen()->boilerplate(), rax, rbx, &offset); |
3935 ASSERT_EQ(size, offset); | 3929 ASSERT_EQ(size, offset); |
3936 } | 3930 } |
3937 | 3931 |
3938 | 3932 |
3939 void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) { | 3933 void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) { |
3940 Handle<FixedArray> constant_properties = | 3934 Handle<FixedArray> constant_properties = |
3941 instr->hydrogen()->constant_properties(); | 3935 instr->hydrogen()->constant_properties(); |
3942 | 3936 |
3943 // Setup the parameters to the stub/runtime call. | 3937 // Setup the parameters to the stub/runtime call. |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4049 void LCodeGen::DoTypeof(LTypeof* instr) { | 4043 void LCodeGen::DoTypeof(LTypeof* instr) { |
4050 LOperand* input = instr->InputAt(0); | 4044 LOperand* input = instr->InputAt(0); |
4051 EmitPushTaggedOperand(input); | 4045 EmitPushTaggedOperand(input); |
4052 CallRuntime(Runtime::kTypeof, 1, instr); | 4046 CallRuntime(Runtime::kTypeof, 1, instr); |
4053 } | 4047 } |
4054 | 4048 |
4055 | 4049 |
4056 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { | 4050 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { |
4057 ASSERT(!operand->IsDoubleRegister()); | 4051 ASSERT(!operand->IsDoubleRegister()); |
4058 if (operand->IsConstantOperand()) { | 4052 if (operand->IsConstantOperand()) { |
4059 __ Push(ToHandle(LConstantOperand::cast(operand))); | 4053 Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); |
4054 if (object->IsSmi()) { | |
4055 __ Push(Handle<Smi>::cast(object)); | |
4056 } else { | |
4057 __ PushHeapObject(Handle<HeapObject>::cast(object)); | |
4058 } | |
4060 } else if (operand->IsRegister()) { | 4059 } else if (operand->IsRegister()) { |
4061 __ push(ToRegister(operand)); | 4060 __ push(ToRegister(operand)); |
4062 } else { | 4061 } else { |
4063 __ push(ToOperand(operand)); | 4062 __ push(ToOperand(operand)); |
4064 } | 4063 } |
4065 } | 4064 } |
4066 | 4065 |
4067 | 4066 |
4068 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 4067 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
4069 Register input = ToRegister(instr->InputAt(0)); | 4068 Register input = ToRegister(instr->InputAt(0)); |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4295 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); | 4294 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); |
4296 ASSERT(osr_pc_offset_ == -1); | 4295 ASSERT(osr_pc_offset_ == -1); |
4297 osr_pc_offset_ = masm()->pc_offset(); | 4296 osr_pc_offset_ = masm()->pc_offset(); |
4298 } | 4297 } |
4299 | 4298 |
4300 #undef __ | 4299 #undef __ |
4301 | 4300 |
4302 } } // namespace v8::internal | 4301 } } // namespace v8::internal |
4303 | 4302 |
4304 #endif // V8_TARGET_ARCH_X64 | 4303 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |