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, offset, value, temp, |
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
argument per line
| |
2165 kSaveFPRegs, EMIT_REMEMBERED_SET, check_needed); | |
2156 } | 2166 } |
2157 } | 2167 } |
2158 | 2168 |
2159 | 2169 |
2160 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { | 2170 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { |
2161 Register object = ToRegister(instr->object()); | 2171 Register object = ToRegister(instr->object()); |
2162 Register result = ToRegister(instr->result()); | 2172 Register result = ToRegister(instr->result()); |
2163 if (instr->hydrogen()->is_in_object()) { | 2173 if (instr->hydrogen()->is_in_object()) { |
2164 __ mov(result, FieldOperand(object, instr->hydrogen()->offset())); | 2174 __ mov(result, FieldOperand(object, instr->hydrogen()->offset())); |
2165 } else { | 2175 } else { |
(...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3139 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 3149 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
3140 Register object = ToRegister(instr->object()); | 3150 Register object = ToRegister(instr->object()); |
3141 Register value = ToRegister(instr->value()); | 3151 Register value = ToRegister(instr->value()); |
3142 int offset = instr->offset(); | 3152 int offset = instr->offset(); |
3143 | 3153 |
3144 if (!instr->transition().is_null()) { | 3154 if (!instr->transition().is_null()) { |
3145 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); | 3155 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); |
3146 } | 3156 } |
3147 | 3157 |
3148 // Do the store. | 3158 // Do the store. |
3159 HType type = instr->hydrogen()->value()->type(); | |
3160 SmiCheck check_needed = | |
3161 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
3149 if (instr->is_in_object()) { | 3162 if (instr->is_in_object()) { |
3150 __ mov(FieldOperand(object, offset), value); | 3163 __ mov(FieldOperand(object, offset), value); |
3151 if (instr->needs_write_barrier()) { | 3164 if (instr->hydrogen()->NeedsWriteBarrier()) { |
3152 Register temp = ToRegister(instr->TempAt(0)); | 3165 Register temp = ToRegister(instr->TempAt(0)); |
3153 // Update the write barrier for the object for in-object properties. | 3166 // Update the write barrier for the object for in-object properties. |
3154 __ RecordWriteField(object, offset, value, temp, kSaveFPRegs); | 3167 __ RecordWriteField(object, offset, value, temp, |
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
argument per line
| |
3168 kSaveFPRegs, EMIT_REMEMBERED_SET, check_needed); | |
3155 } | 3169 } |
3156 } else { | 3170 } else { |
3157 Register temp = ToRegister(instr->TempAt(0)); | 3171 Register temp = ToRegister(instr->TempAt(0)); |
3158 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); | 3172 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); |
3159 __ mov(FieldOperand(temp, offset), value); | 3173 __ mov(FieldOperand(temp, offset), value); |
3160 if (instr->needs_write_barrier()) { | 3174 if (instr->hydrogen()->NeedsWriteBarrier()) { |
3161 // Update the write barrier for the properties array. | 3175 // Update the write barrier for the properties array. |
3162 // object is used as a scratch register. | 3176 // object is used as a scratch register. |
3163 __ RecordWriteField(temp, offset, value, object, kSaveFPRegs); | 3177 __ RecordWriteField(temp, offset, value, object, |
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
argument per line
| |
3178 kSaveFPRegs, EMIT_REMEMBERED_SET, check_needed); | |
3164 } | 3179 } |
3165 } | 3180 } |
3166 } | 3181 } |
3167 | 3182 |
3168 | 3183 |
3169 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 3184 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
3170 ASSERT(ToRegister(instr->context()).is(esi)); | 3185 ASSERT(ToRegister(instr->context()).is(esi)); |
3171 ASSERT(ToRegister(instr->object()).is(edx)); | 3186 ASSERT(ToRegister(instr->object()).is(edx)); |
3172 ASSERT(ToRegister(instr->value()).is(eax)); | 3187 ASSERT(ToRegister(instr->value()).is(eax)); |
3173 | 3188 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3252 __ mov(FieldOperand(elements, offset), value); | 3267 __ mov(FieldOperand(elements, offset), value); |
3253 } else { | 3268 } else { |
3254 __ mov(FieldOperand(elements, | 3269 __ mov(FieldOperand(elements, |
3255 key, | 3270 key, |
3256 times_pointer_size, | 3271 times_pointer_size, |
3257 FixedArray::kHeaderSize), | 3272 FixedArray::kHeaderSize), |
3258 value); | 3273 value); |
3259 } | 3274 } |
3260 | 3275 |
3261 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3276 if (instr->hydrogen()->NeedsWriteBarrier()) { |
3277 HType type = instr->hydrogen()->value()->type(); | |
3278 SmiCheck check_needed = | |
3279 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
3262 // Compute address of modified element and store it into key register. | 3280 // Compute address of modified element and store it into key register. |
3263 __ lea(key, | 3281 __ lea(key, |
3264 FieldOperand(elements, | 3282 FieldOperand(elements, |
3265 key, | 3283 key, |
3266 times_pointer_size, | 3284 times_pointer_size, |
3267 FixedArray::kHeaderSize)); | 3285 FixedArray::kHeaderSize)); |
3268 __ RecordWrite(elements, key, value, kSaveFPRegs); | 3286 __ RecordWrite(elements, key, value, kSaveFPRegs, |
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
argument per line
| |
3287 EMIT_REMEMBERED_SET, check_needed); | |
3269 } | 3288 } |
3270 } | 3289 } |
3271 | 3290 |
3272 | 3291 |
3273 void LCodeGen::DoStoreKeyedFastDoubleElement( | 3292 void LCodeGen::DoStoreKeyedFastDoubleElement( |
3274 LStoreKeyedFastDoubleElement* instr) { | 3293 LStoreKeyedFastDoubleElement* instr) { |
3275 XMMRegister value = ToDoubleRegister(instr->value()); | 3294 XMMRegister value = ToDoubleRegister(instr->value()); |
3276 Label have_value; | 3295 Label have_value; |
3277 | 3296 |
3278 __ ucomisd(value, value); | 3297 __ ucomisd(value, value); |
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4240 } | 4259 } |
4241 | 4260 |
4242 | 4261 |
4243 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 4262 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
4244 Register input = ToRegister(instr->InputAt(0)); | 4263 Register input = ToRegister(instr->InputAt(0)); |
4245 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 4264 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
4246 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 4265 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
4247 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 4266 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
4248 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 4267 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
4249 | 4268 |
4250 Condition final_branch_condition = EmitTypeofIs(true_label, | 4269 Condition final_branch_condition = |
4251 false_label, | 4270 EmitTypeofIs(true_label, false_label, input, instr->type_literal()); |
4252 input, | 4271 if (final_branch_condition != no_condition) { |
4253 instr->type_literal()); | 4272 EmitBranch(true_block, false_block, final_branch_condition); |
4254 | 4273 } |
4255 EmitBranch(true_block, false_block, final_branch_condition); | |
4256 } | 4274 } |
4257 | 4275 |
4258 | 4276 |
4259 Condition LCodeGen::EmitTypeofIs(Label* true_label, | 4277 Condition LCodeGen::EmitTypeofIs(Label* true_label, |
4260 Label* false_label, | 4278 Label* false_label, |
4261 Register input, | 4279 Register input, |
4262 Handle<String> type_name) { | 4280 Handle<String> type_name) { |
4263 Condition final_branch_condition = no_condition; | 4281 Condition final_branch_condition = no_condition; |
4264 if (type_name->Equals(heap()->number_symbol())) { | 4282 if (type_name->Equals(heap()->number_symbol())) { |
4265 __ JumpIfSmi(input, true_label); | 4283 __ 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); | 4330 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); |
4313 __ j(below, false_label); | 4331 __ j(below, false_label); |
4314 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 4332 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
4315 __ j(above, false_label); | 4333 __ j(above, false_label); |
4316 // Check for undetectable objects => false. | 4334 // Check for undetectable objects => false. |
4317 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 4335 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
4318 1 << Map::kIsUndetectable); | 4336 1 << Map::kIsUndetectable); |
4319 final_branch_condition = zero; | 4337 final_branch_condition = zero; |
4320 | 4338 |
4321 } else { | 4339 } else { |
4322 final_branch_condition = not_equal; | |
4323 __ jmp(false_label); | 4340 __ jmp(false_label); |
4324 // A dead branch instruction will be generated after this point. | |
4325 } | 4341 } |
4326 | |
4327 return final_branch_condition; | 4342 return final_branch_condition; |
4328 } | 4343 } |
4329 | 4344 |
4330 | 4345 |
4331 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 4346 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
4332 Register temp = ToRegister(instr->TempAt(0)); | 4347 Register temp = ToRegister(instr->TempAt(0)); |
4333 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 4348 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
4334 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 4349 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
4335 | 4350 |
4336 EmitIsConstructCall(temp); | 4351 EmitIsConstructCall(temp); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4489 env->deoptimization_index()); | 4504 env->deoptimization_index()); |
4490 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); | 4505 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); |
4491 } | 4506 } |
4492 | 4507 |
4493 | 4508 |
4494 #undef __ | 4509 #undef __ |
4495 | 4510 |
4496 } } // namespace v8::internal | 4511 } } // namespace v8::internal |
4497 | 4512 |
4498 #endif // V8_TARGET_ARCH_IA32 | 4513 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |