| 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 2098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2109 // it as no longer deleted. We deoptimize in that case. | 2109 // it as no longer deleted. We deoptimize in that case. |
| 2110 if (instr->hydrogen()->RequiresHoleCheck()) { | 2110 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 2111 __ cmp(FieldOperand(object, offset), factory()->the_hole_value()); | 2111 __ cmp(FieldOperand(object, offset), factory()->the_hole_value()); |
| 2112 DeoptimizeIf(equal, instr->environment()); | 2112 DeoptimizeIf(equal, instr->environment()); |
| 2113 } | 2113 } |
| 2114 | 2114 |
| 2115 // Store the value. | 2115 // Store the value. |
| 2116 __ mov(FieldOperand(object, offset), value); | 2116 __ mov(FieldOperand(object, offset), value); |
| 2117 | 2117 |
| 2118 // Cells are always in the remembered set. | 2118 // Cells are always in the remembered set. |
| 2119 __ RecordWriteField(object, | 2119 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 2120 offset, | 2120 HType type = instr->hydrogen()->value()->type(); |
| 2121 value, | 2121 SmiCheck check_needed = |
| 2122 address, | 2122 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 2123 kSaveFPRegs, | 2123 __ RecordWriteField(object, |
| 2124 OMIT_REMEMBERED_SET); | 2124 offset, |
| 2125 value, |
| 2126 address, |
| 2127 kSaveFPRegs, |
| 2128 OMIT_REMEMBERED_SET, |
| 2129 check_needed); |
| 2130 } |
| 2125 } | 2131 } |
| 2126 | 2132 |
| 2127 | 2133 |
| 2128 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { | 2134 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { |
| 2129 ASSERT(ToRegister(instr->context()).is(esi)); | 2135 ASSERT(ToRegister(instr->context()).is(esi)); |
| 2130 ASSERT(ToRegister(instr->global_object()).is(edx)); | 2136 ASSERT(ToRegister(instr->global_object()).is(edx)); |
| 2131 ASSERT(ToRegister(instr->value()).is(eax)); | 2137 ASSERT(ToRegister(instr->value()).is(eax)); |
| 2132 | 2138 |
| 2133 __ mov(ecx, instr->name()); | 2139 __ mov(ecx, instr->name()); |
| 2134 Handle<Code> ic = instr->strict_mode() | 2140 Handle<Code> ic = instr->strict_mode() |
| 2135 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 2141 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 2136 : isolate()->builtins()->StoreIC_Initialize(); | 2142 : isolate()->builtins()->StoreIC_Initialize(); |
| 2137 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); | 2143 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); |
| 2138 } | 2144 } |
| 2139 | 2145 |
| 2140 | 2146 |
| 2141 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 2147 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
| 2142 Register context = ToRegister(instr->context()); | 2148 Register context = ToRegister(instr->context()); |
| 2143 Register result = ToRegister(instr->result()); | 2149 Register result = ToRegister(instr->result()); |
| 2144 __ mov(result, ContextOperand(context, instr->slot_index())); | 2150 __ mov(result, ContextOperand(context, instr->slot_index())); |
| 2145 } | 2151 } |
| 2146 | 2152 |
| 2147 | 2153 |
| 2148 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { | 2154 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { |
| 2149 Register context = ToRegister(instr->context()); | 2155 Register context = ToRegister(instr->context()); |
| 2150 Register value = ToRegister(instr->value()); | 2156 Register value = ToRegister(instr->value()); |
| 2151 __ mov(ContextOperand(context, instr->slot_index()), value); | 2157 __ mov(ContextOperand(context, instr->slot_index()), value); |
| 2152 if (instr->needs_write_barrier()) { | 2158 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 2159 HType type = instr->hydrogen()->value()->type(); |
| 2160 SmiCheck check_needed = |
| 2161 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 2153 Register temp = ToRegister(instr->TempAt(0)); | 2162 Register temp = ToRegister(instr->TempAt(0)); |
| 2154 int offset = Context::SlotOffset(instr->slot_index()); | 2163 int offset = Context::SlotOffset(instr->slot_index()); |
| 2155 __ RecordWriteContextSlot(context, offset, value, temp, kSaveFPRegs); | 2164 __ RecordWriteContextSlot(context, |
| 2165 offset, |
| 2166 value, |
| 2167 temp, |
| 2168 kSaveFPRegs, |
| 2169 EMIT_REMEMBERED_SET, |
| 2170 check_needed); |
| 2156 } | 2171 } |
| 2157 } | 2172 } |
| 2158 | 2173 |
| 2159 | 2174 |
| 2160 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { | 2175 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { |
| 2161 Register object = ToRegister(instr->object()); | 2176 Register object = ToRegister(instr->object()); |
| 2162 Register result = ToRegister(instr->result()); | 2177 Register result = ToRegister(instr->result()); |
| 2163 if (instr->hydrogen()->is_in_object()) { | 2178 if (instr->hydrogen()->is_in_object()) { |
| 2164 __ mov(result, FieldOperand(object, instr->hydrogen()->offset())); | 2179 __ mov(result, FieldOperand(object, instr->hydrogen()->offset())); |
| 2165 } else { | 2180 } else { |
| (...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3139 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 3154 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
| 3140 Register object = ToRegister(instr->object()); | 3155 Register object = ToRegister(instr->object()); |
| 3141 Register value = ToRegister(instr->value()); | 3156 Register value = ToRegister(instr->value()); |
| 3142 int offset = instr->offset(); | 3157 int offset = instr->offset(); |
| 3143 | 3158 |
| 3144 if (!instr->transition().is_null()) { | 3159 if (!instr->transition().is_null()) { |
| 3145 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); | 3160 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); |
| 3146 } | 3161 } |
| 3147 | 3162 |
| 3148 // Do the store. | 3163 // Do the store. |
| 3164 HType type = instr->hydrogen()->value()->type(); |
| 3165 SmiCheck check_needed = |
| 3166 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 3149 if (instr->is_in_object()) { | 3167 if (instr->is_in_object()) { |
| 3150 __ mov(FieldOperand(object, offset), value); | 3168 __ mov(FieldOperand(object, offset), value); |
| 3151 if (instr->needs_write_barrier()) { | 3169 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 3152 Register temp = ToRegister(instr->TempAt(0)); | 3170 Register temp = ToRegister(instr->TempAt(0)); |
| 3153 // Update the write barrier for the object for in-object properties. | 3171 // Update the write barrier for the object for in-object properties. |
| 3154 __ RecordWriteField(object, offset, value, temp, kSaveFPRegs); | 3172 __ RecordWriteField(object, |
| 3173 offset, |
| 3174 value, |
| 3175 temp, |
| 3176 kSaveFPRegs, |
| 3177 EMIT_REMEMBERED_SET, |
| 3178 check_needed); |
| 3155 } | 3179 } |
| 3156 } else { | 3180 } else { |
| 3157 Register temp = ToRegister(instr->TempAt(0)); | 3181 Register temp = ToRegister(instr->TempAt(0)); |
| 3158 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); | 3182 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); |
| 3159 __ mov(FieldOperand(temp, offset), value); | 3183 __ mov(FieldOperand(temp, offset), value); |
| 3160 if (instr->needs_write_barrier()) { | 3184 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 3161 // Update the write barrier for the properties array. | 3185 // Update the write barrier for the properties array. |
| 3162 // object is used as a scratch register. | 3186 // object is used as a scratch register. |
| 3163 __ RecordWriteField(temp, offset, value, object, kSaveFPRegs); | 3187 __ RecordWriteField(temp, |
| 3188 offset, |
| 3189 value, |
| 3190 object, |
| 3191 kSaveFPRegs, |
| 3192 EMIT_REMEMBERED_SET, |
| 3193 check_needed); |
| 3164 } | 3194 } |
| 3165 } | 3195 } |
| 3166 } | 3196 } |
| 3167 | 3197 |
| 3168 | 3198 |
| 3169 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 3199 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
| 3170 ASSERT(ToRegister(instr->context()).is(esi)); | 3200 ASSERT(ToRegister(instr->context()).is(esi)); |
| 3171 ASSERT(ToRegister(instr->object()).is(edx)); | 3201 ASSERT(ToRegister(instr->object()).is(edx)); |
| 3172 ASSERT(ToRegister(instr->value()).is(eax)); | 3202 ASSERT(ToRegister(instr->value()).is(eax)); |
| 3173 | 3203 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3252 __ mov(FieldOperand(elements, offset), value); | 3282 __ mov(FieldOperand(elements, offset), value); |
| 3253 } else { | 3283 } else { |
| 3254 __ mov(FieldOperand(elements, | 3284 __ mov(FieldOperand(elements, |
| 3255 key, | 3285 key, |
| 3256 times_pointer_size, | 3286 times_pointer_size, |
| 3257 FixedArray::kHeaderSize), | 3287 FixedArray::kHeaderSize), |
| 3258 value); | 3288 value); |
| 3259 } | 3289 } |
| 3260 | 3290 |
| 3261 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3291 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 3292 HType type = instr->hydrogen()->value()->type(); |
| 3293 SmiCheck check_needed = |
| 3294 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 3262 // Compute address of modified element and store it into key register. | 3295 // Compute address of modified element and store it into key register. |
| 3263 __ lea(key, | 3296 __ lea(key, |
| 3264 FieldOperand(elements, | 3297 FieldOperand(elements, |
| 3265 key, | 3298 key, |
| 3266 times_pointer_size, | 3299 times_pointer_size, |
| 3267 FixedArray::kHeaderSize)); | 3300 FixedArray::kHeaderSize)); |
| 3268 __ RecordWrite(elements, key, value, kSaveFPRegs); | 3301 __ RecordWrite(elements, |
| 3302 key, |
| 3303 value, |
| 3304 kSaveFPRegs, |
| 3305 EMIT_REMEMBERED_SET, |
| 3306 check_needed); |
| 3269 } | 3307 } |
| 3270 } | 3308 } |
| 3271 | 3309 |
| 3272 | 3310 |
| 3273 void LCodeGen::DoStoreKeyedFastDoubleElement( | 3311 void LCodeGen::DoStoreKeyedFastDoubleElement( |
| 3274 LStoreKeyedFastDoubleElement* instr) { | 3312 LStoreKeyedFastDoubleElement* instr) { |
| 3275 XMMRegister value = ToDoubleRegister(instr->value()); | 3313 XMMRegister value = ToDoubleRegister(instr->value()); |
| 3276 Label have_value; | 3314 Label have_value; |
| 3277 | 3315 |
| 3278 __ ucomisd(value, value); | 3316 __ ucomisd(value, value); |
| (...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4240 } | 4278 } |
| 4241 | 4279 |
| 4242 | 4280 |
| 4243 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 4281 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
| 4244 Register input = ToRegister(instr->InputAt(0)); | 4282 Register input = ToRegister(instr->InputAt(0)); |
| 4245 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 4283 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 4246 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 4284 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 4247 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 4285 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| 4248 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 4286 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 4249 | 4287 |
| 4250 Condition final_branch_condition = EmitTypeofIs(true_label, | 4288 Condition final_branch_condition = |
| 4251 false_label, | 4289 EmitTypeofIs(true_label, false_label, input, instr->type_literal()); |
| 4252 input, | 4290 if (final_branch_condition != no_condition) { |
| 4253 instr->type_literal()); | 4291 EmitBranch(true_block, false_block, final_branch_condition); |
| 4254 | 4292 } |
| 4255 EmitBranch(true_block, false_block, final_branch_condition); | |
| 4256 } | 4293 } |
| 4257 | 4294 |
| 4258 | 4295 |
| 4259 Condition LCodeGen::EmitTypeofIs(Label* true_label, | 4296 Condition LCodeGen::EmitTypeofIs(Label* true_label, |
| 4260 Label* false_label, | 4297 Label* false_label, |
| 4261 Register input, | 4298 Register input, |
| 4262 Handle<String> type_name) { | 4299 Handle<String> type_name) { |
| 4263 Condition final_branch_condition = no_condition; | 4300 Condition final_branch_condition = no_condition; |
| 4264 if (type_name->Equals(heap()->number_symbol())) { | 4301 if (type_name->Equals(heap()->number_symbol())) { |
| 4265 __ JumpIfSmi(input, true_label); | 4302 __ JumpIfSmi(input, true_label); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4312 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); | 4349 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); |
| 4313 __ j(below, false_label); | 4350 __ j(below, false_label); |
| 4314 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 4351 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
| 4315 __ j(above, false_label); | 4352 __ j(above, false_label); |
| 4316 // Check for undetectable objects => false. | 4353 // Check for undetectable objects => false. |
| 4317 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 4354 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
| 4318 1 << Map::kIsUndetectable); | 4355 1 << Map::kIsUndetectable); |
| 4319 final_branch_condition = zero; | 4356 final_branch_condition = zero; |
| 4320 | 4357 |
| 4321 } else { | 4358 } else { |
| 4322 final_branch_condition = not_equal; | |
| 4323 __ jmp(false_label); | 4359 __ jmp(false_label); |
| 4324 // A dead branch instruction will be generated after this point. | |
| 4325 } | 4360 } |
| 4326 | |
| 4327 return final_branch_condition; | 4361 return final_branch_condition; |
| 4328 } | 4362 } |
| 4329 | 4363 |
| 4330 | 4364 |
| 4331 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 4365 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
| 4332 Register temp = ToRegister(instr->TempAt(0)); | 4366 Register temp = ToRegister(instr->TempAt(0)); |
| 4333 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 4367 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 4334 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 4368 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 4335 | 4369 |
| 4336 EmitIsConstructCall(temp); | 4370 EmitIsConstructCall(temp); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4489 env->deoptimization_index()); | 4523 env->deoptimization_index()); |
| 4490 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); | 4524 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); |
| 4491 } | 4525 } |
| 4492 | 4526 |
| 4493 | 4527 |
| 4494 #undef __ | 4528 #undef __ |
| 4495 | 4529 |
| 4496 } } // namespace v8::internal | 4530 } } // namespace v8::internal |
| 4497 | 4531 |
| 4498 #endif // V8_TARGET_ARCH_IA32 | 4532 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |