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 2037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2048 // to update the property details in the property dictionary to mark | 2048 // to update the property details in the property dictionary to mark |
2049 // it as no longer deleted. We deoptimize in that case. | 2049 // it as no longer deleted. We deoptimize in that case. |
2050 if (instr->hydrogen()->RequiresHoleCheck()) { | 2050 if (instr->hydrogen()->RequiresHoleCheck()) { |
2051 __ CompareRoot(Operand(address, 0), Heap::kTheHoleValueRootIndex); | 2051 __ CompareRoot(Operand(address, 0), Heap::kTheHoleValueRootIndex); |
2052 DeoptimizeIf(equal, instr->environment()); | 2052 DeoptimizeIf(equal, instr->environment()); |
2053 } | 2053 } |
2054 | 2054 |
2055 // Store the value. | 2055 // Store the value. |
2056 __ movq(Operand(address, 0), value); | 2056 __ movq(Operand(address, 0), value); |
2057 | 2057 |
2058 Label smi_store; | 2058 if (instr->hydrogen()->NeedsWriteBarrier()) { |
2059 __ JumpIfSmi(value, &smi_store, Label::kNear); | 2059 Label smi_store; |
2060 HType type = instr->hydrogen()->value()->type(); | |
2061 if (!type.IsHeapNumber() && !type.IsString() && !type.IsNonPrimitive()) { | |
2062 __ JumpIfSmi(value, &smi_store, Label::kNear); | |
2063 } | |
2060 | 2064 |
2061 int offset = JSGlobalPropertyCell::kValueOffset - kHeapObjectTag; | 2065 int offset = JSGlobalPropertyCell::kValueOffset - kHeapObjectTag; |
2062 __ lea(object, Operand(address, -offset)); | 2066 __ lea(object, Operand(address, -offset)); |
2063 // Cells are always in the remembered set. | 2067 // Cells are always in the remembered set. |
2064 __ RecordWrite(object, | 2068 __ RecordWrite(object, |
2065 address, | 2069 address, |
2066 value, | 2070 value, |
2067 kSaveFPRegs, | 2071 kSaveFPRegs, |
2068 OMIT_REMEMBERED_SET, | 2072 OMIT_REMEMBERED_SET, |
2069 OMIT_SMI_CHECK); | 2073 OMIT_SMI_CHECK); |
2070 __ bind(&smi_store); | 2074 __ bind(&smi_store); |
2075 } | |
2071 } | 2076 } |
2072 | 2077 |
2073 | 2078 |
2074 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { | 2079 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { |
2075 ASSERT(ToRegister(instr->global_object()).is(rdx)); | 2080 ASSERT(ToRegister(instr->global_object()).is(rdx)); |
2076 ASSERT(ToRegister(instr->value()).is(rax)); | 2081 ASSERT(ToRegister(instr->value()).is(rax)); |
2077 | 2082 |
2078 __ Move(rcx, instr->name()); | 2083 __ Move(rcx, instr->name()); |
2079 Handle<Code> ic = instr->strict_mode() | 2084 Handle<Code> ic = instr->strict_mode() |
2080 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 2085 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
2081 : isolate()->builtins()->StoreIC_Initialize(); | 2086 : isolate()->builtins()->StoreIC_Initialize(); |
2082 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); | 2087 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); |
2083 } | 2088 } |
2084 | 2089 |
2085 | 2090 |
2086 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 2091 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
2087 Register context = ToRegister(instr->context()); | 2092 Register context = ToRegister(instr->context()); |
2088 Register result = ToRegister(instr->result()); | 2093 Register result = ToRegister(instr->result()); |
2089 __ movq(result, ContextOperand(context, instr->slot_index())); | 2094 __ movq(result, ContextOperand(context, instr->slot_index())); |
2090 } | 2095 } |
2091 | 2096 |
2092 | 2097 |
2093 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { | 2098 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { |
2094 Register context = ToRegister(instr->context()); | 2099 Register context = ToRegister(instr->context()); |
2095 Register value = ToRegister(instr->value()); | 2100 Register value = ToRegister(instr->value()); |
2096 __ movq(ContextOperand(context, instr->slot_index()), value); | 2101 __ movq(ContextOperand(context, instr->slot_index()), value); |
2097 if (instr->needs_write_barrier()) { | 2102 if (instr->hydrogen()->NeedsWriteBarrier()) { |
2103 HType type = instr->hydrogen()->value()->type(); | |
2104 SmiCheck check_needed = | |
2105 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
2098 int offset = Context::SlotOffset(instr->slot_index()); | 2106 int offset = Context::SlotOffset(instr->slot_index()); |
2099 Register scratch = ToRegister(instr->TempAt(0)); | 2107 Register scratch = ToRegister(instr->TempAt(0)); |
2100 __ RecordWriteContextSlot(context, offset, value, scratch, kSaveFPRegs); | 2108 __ RecordWriteContextSlot(context, offset, value, scratch, kSaveFPRegs, |
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
argument per line
| |
2109 EMIT_REMEMBERED_SET, check_needed); | |
2101 } | 2110 } |
2102 } | 2111 } |
2103 | 2112 |
2104 | 2113 |
2105 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { | 2114 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { |
2106 Register object = ToRegister(instr->InputAt(0)); | 2115 Register object = ToRegister(instr->InputAt(0)); |
2107 Register result = ToRegister(instr->result()); | 2116 Register result = ToRegister(instr->result()); |
2108 if (instr->hydrogen()->is_in_object()) { | 2117 if (instr->hydrogen()->is_in_object()) { |
2109 __ movq(result, FieldOperand(object, instr->hydrogen()->offset())); | 2118 __ movq(result, FieldOperand(object, instr->hydrogen()->offset())); |
2110 } else { | 2119 } else { |
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3054 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 3063 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
3055 Register object = ToRegister(instr->object()); | 3064 Register object = ToRegister(instr->object()); |
3056 Register value = ToRegister(instr->value()); | 3065 Register value = ToRegister(instr->value()); |
3057 int offset = instr->offset(); | 3066 int offset = instr->offset(); |
3058 | 3067 |
3059 if (!instr->transition().is_null()) { | 3068 if (!instr->transition().is_null()) { |
3060 __ Move(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); | 3069 __ Move(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); |
3061 } | 3070 } |
3062 | 3071 |
3063 // Do the store. | 3072 // Do the store. |
3073 HType type = instr->hydrogen()->value()->type(); | |
3074 SmiCheck check_needed = | |
3075 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
3064 if (instr->is_in_object()) { | 3076 if (instr->is_in_object()) { |
3065 __ movq(FieldOperand(object, offset), value); | 3077 __ movq(FieldOperand(object, offset), value); |
3066 if (instr->needs_write_barrier()) { | 3078 if (instr->hydrogen()->NeedsWriteBarrier()) { |
3067 Register temp = ToRegister(instr->TempAt(0)); | 3079 Register temp = ToRegister(instr->TempAt(0)); |
3068 // Update the write barrier for the object for in-object properties. | 3080 // Update the write barrier for the object for in-object properties. |
3069 __ RecordWriteField(object, offset, value, temp, kSaveFPRegs); | 3081 __ RecordWriteField(object, offset, value, temp, kSaveFPRegs, |
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
argument per line
| |
3082 EMIT_REMEMBERED_SET, check_needed); | |
3070 } | 3083 } |
3071 } else { | 3084 } else { |
3072 Register temp = ToRegister(instr->TempAt(0)); | 3085 Register temp = ToRegister(instr->TempAt(0)); |
3073 __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset)); | 3086 __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset)); |
3074 __ movq(FieldOperand(temp, offset), value); | 3087 __ movq(FieldOperand(temp, offset), value); |
3075 if (instr->needs_write_barrier()) { | 3088 if (instr->hydrogen()->NeedsWriteBarrier()) { |
3076 // Update the write barrier for the properties array. | 3089 // Update the write barrier for the properties array. |
3077 // object is used as a scratch register. | 3090 // object is used as a scratch register. |
3078 __ RecordWriteField(temp, offset, value, object, kSaveFPRegs); | 3091 __ RecordWriteField(temp, offset, value, object, kSaveFPRegs, |
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
argument per line
| |
3092 EMIT_REMEMBERED_SET, check_needed); | |
3079 } | 3093 } |
3080 } | 3094 } |
3081 } | 3095 } |
3082 | 3096 |
3083 | 3097 |
3084 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 3098 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
3085 ASSERT(ToRegister(instr->object()).is(rdx)); | 3099 ASSERT(ToRegister(instr->object()).is(rdx)); |
3086 ASSERT(ToRegister(instr->value()).is(rax)); | 3100 ASSERT(ToRegister(instr->value()).is(rax)); |
3087 | 3101 |
3088 __ Move(rcx, instr->hydrogen()->name()); | 3102 __ Move(rcx, instr->hydrogen()->name()); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3175 __ movq(FieldOperand(elements, offset), value); | 3189 __ movq(FieldOperand(elements, offset), value); |
3176 } else { | 3190 } else { |
3177 __ movq(FieldOperand(elements, | 3191 __ movq(FieldOperand(elements, |
3178 key, | 3192 key, |
3179 times_pointer_size, | 3193 times_pointer_size, |
3180 FixedArray::kHeaderSize), | 3194 FixedArray::kHeaderSize), |
3181 value); | 3195 value); |
3182 } | 3196 } |
3183 | 3197 |
3184 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3198 if (instr->hydrogen()->NeedsWriteBarrier()) { |
3199 HType type = instr->hydrogen()->value()->type(); | |
3200 SmiCheck check_needed = | |
3201 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
3185 // Compute address of modified element and store it into key register. | 3202 // Compute address of modified element and store it into key register. |
3186 __ lea(key, FieldOperand(elements, | 3203 __ lea(key, FieldOperand(elements, |
3187 key, | 3204 key, |
3188 times_pointer_size, | 3205 times_pointer_size, |
3189 FixedArray::kHeaderSize)); | 3206 FixedArray::kHeaderSize)); |
3190 __ RecordWrite(elements, key, value, kSaveFPRegs); | 3207 __ RecordWrite(elements, key, value, kSaveFPRegs, |
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
argument per line
| |
3208 EMIT_REMEMBERED_SET, check_needed); | |
3191 } | 3209 } |
3192 } | 3210 } |
3193 | 3211 |
3194 | 3212 |
3195 void LCodeGen::DoStoreKeyedFastDoubleElement( | 3213 void LCodeGen::DoStoreKeyedFastDoubleElement( |
3196 LStoreKeyedFastDoubleElement* instr) { | 3214 LStoreKeyedFastDoubleElement* instr) { |
3197 XMMRegister value = ToDoubleRegister(instr->value()); | 3215 XMMRegister value = ToDoubleRegister(instr->value()); |
3198 Label have_value; | 3216 Label have_value; |
3199 | 3217 |
3200 __ ucomisd(value, value); | 3218 __ ucomisd(value, value); |
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3968 } | 3986 } |
3969 | 3987 |
3970 | 3988 |
3971 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 3989 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
3972 Register input = ToRegister(instr->InputAt(0)); | 3990 Register input = ToRegister(instr->InputAt(0)); |
3973 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 3991 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
3974 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 3992 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
3975 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 3993 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
3976 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 3994 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
3977 | 3995 |
3978 Condition final_branch_condition = EmitTypeofIs(true_label, | 3996 Condition final_branch_condition = |
3979 false_label, | 3997 EmitTypeofIs(true_label, false_label, input, instr->type_literal()); |
3980 input, | 3998 if (final_branch_condition != no_condition) { |
3981 instr->type_literal()); | 3999 EmitBranch(true_block, false_block, final_branch_condition); |
3982 | 4000 } |
3983 EmitBranch(true_block, false_block, final_branch_condition); | |
3984 } | 4001 } |
3985 | 4002 |
3986 | 4003 |
3987 Condition LCodeGen::EmitTypeofIs(Label* true_label, | 4004 Condition LCodeGen::EmitTypeofIs(Label* true_label, |
3988 Label* false_label, | 4005 Label* false_label, |
3989 Register input, | 4006 Register input, |
3990 Handle<String> type_name) { | 4007 Handle<String> type_name) { |
3991 Condition final_branch_condition = no_condition; | 4008 Condition final_branch_condition = no_condition; |
3992 if (type_name->Equals(heap()->number_symbol())) { | 4009 if (type_name->Equals(heap()->number_symbol())) { |
3993 __ JumpIfSmi(input, true_label); | 4010 __ JumpIfSmi(input, true_label); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4041 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); | 4058 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); |
4042 __ j(below, false_label); | 4059 __ j(below, false_label); |
4043 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 4060 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
4044 __ j(above, false_label); | 4061 __ j(above, false_label); |
4045 // Check for undetectable objects => false. | 4062 // Check for undetectable objects => false. |
4046 __ testb(FieldOperand(input, Map::kBitFieldOffset), | 4063 __ testb(FieldOperand(input, Map::kBitFieldOffset), |
4047 Immediate(1 << Map::kIsUndetectable)); | 4064 Immediate(1 << Map::kIsUndetectable)); |
4048 final_branch_condition = zero; | 4065 final_branch_condition = zero; |
4049 | 4066 |
4050 } else { | 4067 } else { |
4051 final_branch_condition = never; | |
4052 __ jmp(false_label); | 4068 __ jmp(false_label); |
4053 } | 4069 } |
4054 | 4070 |
4055 return final_branch_condition; | 4071 return final_branch_condition; |
4056 } | 4072 } |
4057 | 4073 |
4058 | 4074 |
4059 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 4075 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
4060 Register temp = ToRegister(instr->TempAt(0)); | 4076 Register temp = ToRegister(instr->TempAt(0)); |
4061 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 4077 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4196 RegisterEnvironmentForDeoptimization(environment); | 4212 RegisterEnvironmentForDeoptimization(environment); |
4197 ASSERT(osr_pc_offset_ == -1); | 4213 ASSERT(osr_pc_offset_ == -1); |
4198 osr_pc_offset_ = masm()->pc_offset(); | 4214 osr_pc_offset_ = masm()->pc_offset(); |
4199 } | 4215 } |
4200 | 4216 |
4201 #undef __ | 4217 #undef __ |
4202 | 4218 |
4203 } } // namespace v8::internal | 4219 } } // namespace v8::internal |
4204 | 4220 |
4205 #endif // V8_TARGET_ARCH_X64 | 4221 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |