Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(691)

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 9227007: Version 3.8.6 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 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
11 // with the distribution. 11 // with the distribution.
(...skipping 1812 matching lines...) Expand 10 before | Expand all | Expand 10 after
1824 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1824 int true_block = chunk_->LookupDestination(instr->true_block_id());
1825 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1825 int false_block = chunk_->LookupDestination(instr->false_block_id());
1826 1826
1827 __ test(FieldOperand(input, String::kHashFieldOffset), 1827 __ test(FieldOperand(input, String::kHashFieldOffset),
1828 Immediate(String::kContainsCachedArrayIndexMask)); 1828 Immediate(String::kContainsCachedArrayIndexMask));
1829 EmitBranch(true_block, false_block, equal); 1829 EmitBranch(true_block, false_block, equal);
1830 } 1830 }
1831 1831
1832 1832
1833 // Branches to a label or falls through with the answer in the z flag. Trashes 1833 // Branches to a label or falls through with the answer in the z flag. Trashes
1834 // the temp registers, but not the input. Only input and temp2 may alias. 1834 // the temp registers, but not the input.
1835 void LCodeGen::EmitClassOfTest(Label* is_true, 1835 void LCodeGen::EmitClassOfTest(Label* is_true,
1836 Label* is_false, 1836 Label* is_false,
1837 Handle<String>class_name, 1837 Handle<String>class_name,
1838 Register input, 1838 Register input,
1839 Register temp, 1839 Register temp,
1840 Register temp2) { 1840 Register temp2) {
1841 ASSERT(!input.is(temp)); 1841 ASSERT(!input.is(temp));
1842 ASSERT(!temp.is(temp2)); // But input and temp2 may be the same register. 1842 ASSERT(!input.is(temp2));
1843 ASSERT(!temp.is(temp2));
1843 __ JumpIfSmi(input, is_false); 1844 __ JumpIfSmi(input, is_false);
1844 1845
1845 if (class_name->IsEqualTo(CStrVector("Function"))) { 1846 if (class_name->IsEqualTo(CStrVector("Function"))) {
1846 // Assuming the following assertions, we can use the same compares to test 1847 // Assuming the following assertions, we can use the same compares to test
1847 // for both being a function type and being in the object type range. 1848 // for both being a function type and being in the object type range.
1848 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 1849 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
1849 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == 1850 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
1850 FIRST_SPEC_OBJECT_TYPE + 1); 1851 FIRST_SPEC_OBJECT_TYPE + 1);
1851 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == 1852 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
1852 LAST_SPEC_OBJECT_TYPE - 1); 1853 LAST_SPEC_OBJECT_TYPE - 1);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 // comparison. 1893 // comparison.
1893 __ cmp(temp, class_name); 1894 __ cmp(temp, class_name);
1894 // End with the answer in the z flag. 1895 // End with the answer in the z flag.
1895 } 1896 }
1896 1897
1897 1898
1898 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 1899 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
1899 Register input = ToRegister(instr->InputAt(0)); 1900 Register input = ToRegister(instr->InputAt(0));
1900 Register temp = ToRegister(instr->TempAt(0)); 1901 Register temp = ToRegister(instr->TempAt(0));
1901 Register temp2 = ToRegister(instr->TempAt(1)); 1902 Register temp2 = ToRegister(instr->TempAt(1));
1902 if (input.is(temp)) { 1903
1903 // Swap.
1904 Register swapper = temp;
1905 temp = temp2;
1906 temp2 = swapper;
1907 }
1908 Handle<String> class_name = instr->hydrogen()->class_name(); 1904 Handle<String> class_name = instr->hydrogen()->class_name();
1909 1905
1910 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1906 int true_block = chunk_->LookupDestination(instr->true_block_id());
1911 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1907 int false_block = chunk_->LookupDestination(instr->false_block_id());
1912 1908
1913 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1909 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1914 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1910 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1915 1911
1916 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); 1912 EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
1917 1913
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 // A Smi is not an instance of anything. 1968 // A Smi is not an instance of anything.
1973 __ JumpIfSmi(object, &false_result); 1969 __ JumpIfSmi(object, &false_result);
1974 1970
1975 // This is the inlined call site instanceof cache. The two occurences of the 1971 // This is the inlined call site instanceof cache. The two occurences of the
1976 // hole value will be patched to the last map/result pair generated by the 1972 // hole value will be patched to the last map/result pair generated by the
1977 // instanceof stub. 1973 // instanceof stub.
1978 Label cache_miss; 1974 Label cache_miss;
1979 Register map = ToRegister(instr->TempAt(0)); 1975 Register map = ToRegister(instr->TempAt(0));
1980 __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); 1976 __ mov(map, FieldOperand(object, HeapObject::kMapOffset));
1981 __ bind(deferred->map_check()); // Label for calculating code patching. 1977 __ bind(deferred->map_check()); // Label for calculating code patching.
1982 __ cmp(map, factory()->the_hole_value()); // Patched to cached map. 1978 Handle<JSGlobalPropertyCell> cache_cell =
1979 factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
1980 __ cmp(map, Operand::Cell(cache_cell)); // Patched to cached map.
1983 __ j(not_equal, &cache_miss, Label::kNear); 1981 __ j(not_equal, &cache_miss, Label::kNear);
1984 __ mov(eax, factory()->the_hole_value()); // Patched to either true or false. 1982 __ mov(eax, factory()->the_hole_value()); // Patched to either true or false.
1985 __ jmp(&done); 1983 __ jmp(&done);
1986 1984
1987 // The inlined call site cache did not match. Check for null and string 1985 // The inlined call site cache did not match. Check for null and string
1988 // before calling the deferred code. 1986 // before calling the deferred code.
1989 __ bind(&cache_miss); 1987 __ bind(&cache_miss);
1990 // Null is not an instance of anything. 1988 // Null is not an instance of anything.
1991 __ cmp(object, factory()->null_value()); 1989 __ cmp(object, factory()->null_value());
1992 __ j(equal, &false_result); 1990 __ j(equal, &false_result);
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after
3009 MathPowStub stub(MathPowStub::INTEGER); 3007 MathPowStub stub(MathPowStub::INTEGER);
3010 __ CallStub(&stub); 3008 __ CallStub(&stub);
3011 } else { 3009 } else {
3012 ASSERT(exponent_type.IsDouble()); 3010 ASSERT(exponent_type.IsDouble());
3013 MathPowStub stub(MathPowStub::DOUBLE); 3011 MathPowStub stub(MathPowStub::DOUBLE);
3014 __ CallStub(&stub); 3012 __ CallStub(&stub);
3015 } 3013 }
3016 } 3014 }
3017 3015
3018 3016
3017 void LCodeGen::DoRandom(LRandom* instr) {
3018 // Having marked this instruction as a call we can use any
3019 // registers.
3020 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3021 ASSERT(ToRegister(instr->InputAt(0)).is(eax));
3022
3023 __ PrepareCallCFunction(1, ebx);
3024 __ mov(eax, FieldOperand(eax, GlobalObject::kGlobalContextOffset));
3025 __ mov(Operand(esp, 0), eax);
3026 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
3027
3028 // Convert 32 random bits in eax to 0.(32 random bits) in a double
3029 // by computing:
3030 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
3031 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
3032 __ movd(xmm2, ebx);
3033 __ movd(xmm1, eax);
3034 __ cvtss2sd(xmm2, xmm2);
3035 __ xorps(xmm1, xmm2);
3036 __ subsd(xmm1, xmm2);
3037 }
3038
3039
3019 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { 3040 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
3020 ASSERT(instr->value()->Equals(instr->result())); 3041 ASSERT(instr->value()->Equals(instr->result()));
3021 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3042 XMMRegister input_reg = ToDoubleRegister(instr->value());
3022 Label positive, done, zero; 3043 Label positive, done, zero;
3023 __ xorps(xmm0, xmm0); 3044 __ xorps(xmm0, xmm0);
3024 __ ucomisd(input_reg, xmm0); 3045 __ ucomisd(input_reg, xmm0);
3025 __ j(above, &positive, Label::kNear); 3046 __ j(above, &positive, Label::kNear);
3026 __ j(equal, &zero, Label::kNear); 3047 __ j(equal, &zero, Label::kNear);
3027 ExternalReference nan = 3048 ExternalReference nan =
3028 ExternalReference::address_of_canonical_non_hole_nan(); 3049 ExternalReference::address_of_canonical_non_hole_nan();
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
3671 ASSERT(input->IsRegister() && input->Equals(instr->result())); 3692 ASSERT(input->IsRegister() && input->Equals(instr->result()));
3672 if (instr->needs_check()) { 3693 if (instr->needs_check()) {
3673 __ test(ToRegister(input), Immediate(kSmiTagMask)); 3694 __ test(ToRegister(input), Immediate(kSmiTagMask));
3674 DeoptimizeIf(not_zero, instr->environment()); 3695 DeoptimizeIf(not_zero, instr->environment());
3675 } 3696 }
3676 __ SmiUntag(ToRegister(input)); 3697 __ SmiUntag(ToRegister(input));
3677 } 3698 }
3678 3699
3679 3700
3680 void LCodeGen::EmitNumberUntagD(Register input_reg, 3701 void LCodeGen::EmitNumberUntagD(Register input_reg,
3702 Register temp_reg,
3681 XMMRegister result_reg, 3703 XMMRegister result_reg,
3682 bool deoptimize_on_undefined, 3704 bool deoptimize_on_undefined,
3705 bool deoptimize_on_minus_zero,
3683 LEnvironment* env) { 3706 LEnvironment* env) {
3684 Label load_smi, done; 3707 Label load_smi, done;
3685 3708
3686 // Smi check. 3709 // Smi check.
3687 __ JumpIfSmi(input_reg, &load_smi, Label::kNear); 3710 __ JumpIfSmi(input_reg, &load_smi, Label::kNear);
3688 3711
3689 // Heap number map check. 3712 // Heap number map check.
3690 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 3713 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
3691 factory()->heap_number_map()); 3714 factory()->heap_number_map());
3692 if (deoptimize_on_undefined) { 3715 if (deoptimize_on_undefined) {
3693 DeoptimizeIf(not_equal, env); 3716 DeoptimizeIf(not_equal, env);
3694 } else { 3717 } else {
3695 Label heap_number; 3718 Label heap_number;
3696 __ j(equal, &heap_number, Label::kNear); 3719 __ j(equal, &heap_number, Label::kNear);
3697 3720
3698 __ cmp(input_reg, factory()->undefined_value()); 3721 __ cmp(input_reg, factory()->undefined_value());
3699 DeoptimizeIf(not_equal, env); 3722 DeoptimizeIf(not_equal, env);
3700 3723
3701 // Convert undefined to NaN. 3724 // Convert undefined to NaN.
3702 ExternalReference nan = 3725 ExternalReference nan =
3703 ExternalReference::address_of_canonical_non_hole_nan(); 3726 ExternalReference::address_of_canonical_non_hole_nan();
3704 __ movdbl(result_reg, Operand::StaticVariable(nan)); 3727 __ movdbl(result_reg, Operand::StaticVariable(nan));
3705 __ jmp(&done, Label::kNear); 3728 __ jmp(&done, Label::kNear);
3706 3729
3707 __ bind(&heap_number); 3730 __ bind(&heap_number);
3708 } 3731 }
3709 // Heap number to XMM conversion. 3732 // Heap number to XMM conversion.
3710 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3733 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
3734 if (deoptimize_on_minus_zero) {
3735 XMMRegister xmm_scratch = xmm0;
3736 __ xorps(xmm_scratch, xmm_scratch);
3737 __ ucomisd(result_reg, xmm_scratch);
3738 __ j(not_zero, &done, Label::kNear);
3739 __ movmskpd(temp_reg, result_reg);
3740 __ test_b(temp_reg, 1);
3741 DeoptimizeIf(not_zero, env);
3742 }
3711 __ jmp(&done, Label::kNear); 3743 __ jmp(&done, Label::kNear);
3712 3744
3713 // Smi to XMM conversion 3745 // Smi to XMM conversion
3714 __ bind(&load_smi); 3746 __ bind(&load_smi);
3715 __ SmiUntag(input_reg); // Untag smi before converting to float. 3747 __ SmiUntag(input_reg); // Untag smi before converting to float.
3716 __ cvtsi2sd(result_reg, Operand(input_reg)); 3748 __ cvtsi2sd(result_reg, Operand(input_reg));
3717 __ SmiTag(input_reg); // Retag smi. 3749 __ SmiTag(input_reg); // Retag smi.
3718 __ bind(&done); 3750 __ bind(&done);
3719 } 3751 }
3720 3752
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
3823 // Smi to int32 conversion 3855 // Smi to int32 conversion
3824 __ SmiUntag(input_reg); // Untag smi. 3856 __ SmiUntag(input_reg); // Untag smi.
3825 3857
3826 __ bind(deferred->exit()); 3858 __ bind(deferred->exit());
3827 } 3859 }
3828 3860
3829 3861
3830 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 3862 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
3831 LOperand* input = instr->InputAt(0); 3863 LOperand* input = instr->InputAt(0);
3832 ASSERT(input->IsRegister()); 3864 ASSERT(input->IsRegister());
3865 LOperand* temp = instr->TempAt(0);
3866 ASSERT(temp == NULL || temp->IsRegister());
3833 LOperand* result = instr->result(); 3867 LOperand* result = instr->result();
3834 ASSERT(result->IsDoubleRegister()); 3868 ASSERT(result->IsDoubleRegister());
3835 3869
3836 Register input_reg = ToRegister(input); 3870 Register input_reg = ToRegister(input);
3837 XMMRegister result_reg = ToDoubleRegister(result); 3871 XMMRegister result_reg = ToDoubleRegister(result);
3838 3872
3839 EmitNumberUntagD(input_reg, result_reg, 3873 bool deoptimize_on_minus_zero =
3874 instr->hydrogen()->deoptimize_on_minus_zero();
3875 Register temp_reg = deoptimize_on_minus_zero ? ToRegister(temp) : no_reg;
3876
3877 EmitNumberUntagD(input_reg,
3878 temp_reg,
3879 result_reg,
3840 instr->hydrogen()->deoptimize_on_undefined(), 3880 instr->hydrogen()->deoptimize_on_undefined(),
3881 deoptimize_on_minus_zero,
3841 instr->environment()); 3882 instr->environment());
3842 } 3883 }
3843 3884
3844 3885
3845 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 3886 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
3846 LOperand* input = instr->InputAt(0); 3887 LOperand* input = instr->InputAt(0);
3847 ASSERT(input->IsDoubleRegister()); 3888 ASSERT(input->IsDoubleRegister());
3848 LOperand* result = instr->result(); 3889 LOperand* result = instr->result();
3849 ASSERT(result->IsRegister()); 3890 ASSERT(result->IsRegister());
3850 3891
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
4026 isolate()->factory()->NewJSGlobalPropertyCell(target); 4067 isolate()->factory()->NewJSGlobalPropertyCell(target);
4027 __ cmp(reg, Operand::Cell(cell)); 4068 __ cmp(reg, Operand::Cell(cell));
4028 } else { 4069 } else {
4029 Operand operand = ToOperand(instr->value()); 4070 Operand operand = ToOperand(instr->value());
4030 __ cmp(operand, target); 4071 __ cmp(operand, target);
4031 } 4072 }
4032 DeoptimizeIf(not_equal, instr->environment()); 4073 DeoptimizeIf(not_equal, instr->environment());
4033 } 4074 }
4034 4075
4035 4076
4077 void LCodeGen::DoCheckMapCommon(Register reg,
4078 Handle<Map> map,
4079 CompareMapMode mode,
4080 LEnvironment* env) {
4081 Label success;
4082 __ CompareMap(reg, map, &success, mode);
4083 DeoptimizeIf(not_equal, env);
4084 __ bind(&success);
4085 }
4086
4087
4036 void LCodeGen::DoCheckMap(LCheckMap* instr) { 4088 void LCodeGen::DoCheckMap(LCheckMap* instr) {
4037 LOperand* input = instr->InputAt(0); 4089 LOperand* input = instr->InputAt(0);
4038 ASSERT(input->IsRegister()); 4090 ASSERT(input->IsRegister());
4039 Register reg = ToRegister(input); 4091 Register reg = ToRegister(input);
4040 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 4092 Handle<Map> map = instr->hydrogen()->map();
4041 instr->hydrogen()->map()); 4093 DoCheckMapCommon(reg, map, instr->hydrogen()->mode(), instr->environment());
4042 DeoptimizeIf(not_equal, instr->environment());
4043 } 4094 }
4044 4095
4045 4096
4046 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 4097 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
4047 XMMRegister value_reg = ToDoubleRegister(instr->unclamped()); 4098 XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
4048 Register result_reg = ToRegister(instr->result()); 4099 Register result_reg = ToRegister(instr->result());
4049 __ ClampDoubleToUint8(value_reg, xmm0, result_reg); 4100 __ ClampDoubleToUint8(value_reg, xmm0, result_reg);
4050 } 4101 }
4051 4102
4052 4103
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
4095 Register reg = ToRegister(instr->TempAt(0)); 4146 Register reg = ToRegister(instr->TempAt(0));
4096 4147
4097 Handle<JSObject> holder = instr->holder(); 4148 Handle<JSObject> holder = instr->holder();
4098 Handle<JSObject> current_prototype = instr->prototype(); 4149 Handle<JSObject> current_prototype = instr->prototype();
4099 4150
4100 // Load prototype object. 4151 // Load prototype object.
4101 __ LoadHeapObject(reg, current_prototype); 4152 __ LoadHeapObject(reg, current_prototype);
4102 4153
4103 // Check prototype maps up to the holder. 4154 // Check prototype maps up to the holder.
4104 while (!current_prototype.is_identical_to(holder)) { 4155 while (!current_prototype.is_identical_to(holder)) {
4105 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 4156 DoCheckMapCommon(reg, Handle<Map>(current_prototype->map()),
4106 Handle<Map>(current_prototype->map())); 4157 ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment());
4107 DeoptimizeIf(not_equal, instr->environment()); 4158
4108 current_prototype = 4159 current_prototype =
4109 Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype())); 4160 Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype()));
4110 // Load next prototype object. 4161 // Load next prototype object.
4111 __ LoadHeapObject(reg, current_prototype); 4162 __ LoadHeapObject(reg, current_prototype);
4112 } 4163 }
4113 4164
4114 // Check the holder map. 4165 // Check the holder map.
4115 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 4166 DoCheckMapCommon(reg, Handle<Map>(current_prototype->map()),
4116 Handle<Map>(current_prototype->map())); 4167 ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment());
4117 DeoptimizeIf(not_equal, instr->environment());
4118 } 4168 }
4119 4169
4120 4170
4121 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { 4171 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
4122 ASSERT(ToRegister(instr->context()).is(esi)); 4172 ASSERT(ToRegister(instr->context()).is(esi));
4123 Heap* heap = isolate()->heap(); 4173 Heap* heap = isolate()->heap();
4124 ElementsKind boilerplate_elements_kind = 4174 ElementsKind boilerplate_elements_kind =
4125 instr->hydrogen()->boilerplate_elements_kind(); 4175 instr->hydrogen()->boilerplate_elements_kind();
4126 4176
4127 // Deopt if the array literal boilerplate ElementsKind is of a type different 4177 // Deopt if the array literal boilerplate ElementsKind is of a type different
4128 // than the expected one. The check isn't necessary if the boilerplate has 4178 // than the expected one. The check isn't necessary if the boilerplate has
4129 // already been converted to FAST_ELEMENTS. 4179 // already been converted to FAST_ELEMENTS.
4130 if (boilerplate_elements_kind != FAST_ELEMENTS) { 4180 if (boilerplate_elements_kind != FAST_ELEMENTS) {
4131 __ LoadHeapObject(eax, instr->hydrogen()->boilerplate_object()); 4181 __ LoadHeapObject(eax, instr->hydrogen()->boilerplate_object());
4132 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 4182 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
4133 // Load the map's "bit field 2". We only need the first byte, 4183 // Load the map's "bit field 2". We only need the first byte,
4134 // but the following masking takes care of that anyway. 4184 // but the following masking takes care of that anyway.
4135 __ mov(ebx, FieldOperand(ebx, Map::kBitField2Offset)); 4185 __ mov(ebx, FieldOperand(ebx, Map::kBitField2Offset));
4136 // Retrieve elements_kind from bit field 2. 4186 // Retrieve elements_kind from bit field 2.
4137 __ and_(ebx, Map::kElementsKindMask); 4187 __ and_(ebx, Map::kElementsKindMask);
4138 __ cmp(ebx, boilerplate_elements_kind << Map::kElementsKindShift); 4188 __ cmp(ebx, boilerplate_elements_kind << Map::kElementsKindShift);
4139 DeoptimizeIf(not_equal, instr->environment()); 4189 DeoptimizeIf(not_equal, instr->environment());
4140 } 4190 }
4141 4191
4142 // Setup the parameters to the stub/runtime call. 4192 // Set up the parameters to the stub/runtime call.
4143 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 4193 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
4144 __ push(FieldOperand(eax, JSFunction::kLiteralsOffset)); 4194 __ push(FieldOperand(eax, JSFunction::kLiteralsOffset));
4145 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); 4195 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
4146 // Boilerplate already exists, constant elements are never accessed. 4196 // Boilerplate already exists, constant elements are never accessed.
4147 // Pass an empty fixed array. 4197 // Pass an empty fixed array.
4148 __ push(Immediate(Handle<FixedArray>(heap->empty_fixed_array()))); 4198 __ push(Immediate(Handle<FixedArray>(heap->empty_fixed_array())));
4149 4199
4150 // Pick the right runtime function or stub to call. 4200 // Pick the right runtime function or stub to call.
4151 int length = instr->hydrogen()->length(); 4201 int length = instr->hydrogen()->length();
4152 if (instr->hydrogen()->IsCopyOnWrite()) { 4202 if (instr->hydrogen()->IsCopyOnWrite()) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
4240 EmitDeepCopy(instr->hydrogen()->boilerplate(), eax, ebx, &offset); 4290 EmitDeepCopy(instr->hydrogen()->boilerplate(), eax, ebx, &offset);
4241 ASSERT_EQ(size, offset); 4291 ASSERT_EQ(size, offset);
4242 } 4292 }
4243 4293
4244 4294
4245 void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) { 4295 void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) {
4246 ASSERT(ToRegister(instr->context()).is(esi)); 4296 ASSERT(ToRegister(instr->context()).is(esi));
4247 Handle<FixedArray> constant_properties = 4297 Handle<FixedArray> constant_properties =
4248 instr->hydrogen()->constant_properties(); 4298 instr->hydrogen()->constant_properties();
4249 4299
4250 // Setup the parameters to the stub/runtime call. 4300 // Set up the parameters to the stub/runtime call.
4251 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 4301 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
4252 __ push(FieldOperand(eax, JSFunction::kLiteralsOffset)); 4302 __ push(FieldOperand(eax, JSFunction::kLiteralsOffset));
4253 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); 4303 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
4254 __ push(Immediate(constant_properties)); 4304 __ push(Immediate(constant_properties));
4255 int flags = instr->hydrogen()->fast_elements() 4305 int flags = instr->hydrogen()->fast_elements()
4256 ? ObjectLiteral::kFastElements 4306 ? ObjectLiteral::kFastElements
4257 : ObjectLiteral::kNoFlags; 4307 : ObjectLiteral::kNoFlags;
4258 flags |= instr->hydrogen()->has_function() 4308 flags |= instr->hydrogen()->has_function()
4259 ? ObjectLiteral::kHasFunction 4309 ? ObjectLiteral::kHasFunction
4260 : ObjectLiteral::kNoFlags; 4310 : ObjectLiteral::kNoFlags;
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
4612 this, pointers, Safepoint::kLazyDeopt); 4662 this, pointers, Safepoint::kLazyDeopt);
4613 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); 4663 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
4614 } 4664 }
4615 4665
4616 4666
4617 #undef __ 4667 #undef __
4618 4668
4619 } } // namespace v8::internal 4669 } } // namespace v8::internal
4620 4670
4621 #endif // V8_TARGET_ARCH_IA32 4671 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698