Chromium Code Reviews| 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 |