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 2233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2244 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | 2244 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); |
2245 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 2245 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
2246 __ cmp(scratch2, ip); | 2246 __ cmp(scratch2, ip); |
2247 DeoptimizeIf(eq, instr->environment()); | 2247 DeoptimizeIf(eq, instr->environment()); |
2248 } | 2248 } |
2249 | 2249 |
2250 // Store the value. | 2250 // Store the value. |
2251 __ str(value, FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | 2251 __ str(value, FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); |
2252 | 2252 |
2253 // Cells are always in the remembered set. | 2253 // Cells are always in the remembered set. |
2254 __ RecordWriteField(scratch, | 2254 if (instr->hydrogen()->NeedsWriteBarrier()) { |
2255 JSGlobalPropertyCell::kValueOffset, | 2255 HType type = instr->hydrogen()->value()->type(); |
2256 value, | 2256 SmiCheck check_needed = |
2257 scratch2, | 2257 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
2258 kLRHasBeenSaved, | 2258 __ RecordWriteField(scratch, |
2259 kSaveFPRegs, | 2259 JSGlobalPropertyCell::kValueOffset, |
2260 OMIT_REMEMBERED_SET); | 2260 value, |
2261 scratch2, | |
2262 kLRHasBeenSaved, | |
2263 kSaveFPRegs, | |
2264 OMIT_REMEMBERED_SET, | |
2265 check_needed); | |
2266 } | |
2261 } | 2267 } |
2262 | 2268 |
2263 | 2269 |
2264 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { | 2270 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { |
2265 ASSERT(ToRegister(instr->global_object()).is(r1)); | 2271 ASSERT(ToRegister(instr->global_object()).is(r1)); |
2266 ASSERT(ToRegister(instr->value()).is(r0)); | 2272 ASSERT(ToRegister(instr->value()).is(r0)); |
2267 | 2273 |
2268 __ mov(r2, Operand(instr->name())); | 2274 __ mov(r2, Operand(instr->name())); |
2269 Handle<Code> ic = instr->strict_mode() | 2275 Handle<Code> ic = instr->strict_mode() |
2270 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 2276 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
2271 : isolate()->builtins()->StoreIC_Initialize(); | 2277 : isolate()->builtins()->StoreIC_Initialize(); |
2272 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); | 2278 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); |
2273 } | 2279 } |
2274 | 2280 |
2275 | 2281 |
2276 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 2282 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
2277 Register context = ToRegister(instr->context()); | 2283 Register context = ToRegister(instr->context()); |
2278 Register result = ToRegister(instr->result()); | 2284 Register result = ToRegister(instr->result()); |
2279 __ ldr(result, ContextOperand(context, instr->slot_index())); | 2285 __ ldr(result, ContextOperand(context, instr->slot_index())); |
2280 } | 2286 } |
2281 | 2287 |
2282 | 2288 |
2283 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { | 2289 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { |
2284 Register context = ToRegister(instr->context()); | 2290 Register context = ToRegister(instr->context()); |
2285 Register value = ToRegister(instr->value()); | 2291 Register value = ToRegister(instr->value()); |
2286 MemOperand target = ContextOperand(context, instr->slot_index()); | 2292 MemOperand target = ContextOperand(context, instr->slot_index()); |
2287 __ str(value, target); | 2293 __ str(value, target); |
2288 if (instr->needs_write_barrier()) { | 2294 if (instr->hydrogen()->NeedsWriteBarrier()) { |
2295 HType type = instr->hydrogen()->value()->type(); | |
2296 SmiCheck check_needed = | |
2297 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
2289 __ RecordWriteContextSlot(context, | 2298 __ RecordWriteContextSlot(context, |
2290 target.offset(), | 2299 target.offset(), |
2291 value, | 2300 value, |
2292 scratch0(), | 2301 scratch0(), |
2293 kLRHasBeenSaved, | 2302 kLRHasBeenSaved, |
2294 kSaveFPRegs); | 2303 kSaveFPRegs, |
2304 EMIT_REMEMBERED_SET, | |
2305 check_needed); | |
2295 } | 2306 } |
2296 } | 2307 } |
2297 | 2308 |
2298 | 2309 |
2299 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { | 2310 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { |
2300 Register object = ToRegister(instr->InputAt(0)); | 2311 Register object = ToRegister(instr->InputAt(0)); |
2301 Register result = ToRegister(instr->result()); | 2312 Register result = ToRegister(instr->result()); |
2302 if (instr->hydrogen()->is_in_object()) { | 2313 if (instr->hydrogen()->is_in_object()) { |
2303 __ ldr(result, FieldMemOperand(object, instr->hydrogen()->offset())); | 2314 __ ldr(result, FieldMemOperand(object, instr->hydrogen()->offset())); |
2304 } else { | 2315 } else { |
(...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3290 int offset = instr->offset(); | 3301 int offset = instr->offset(); |
3291 | 3302 |
3292 ASSERT(!object.is(value)); | 3303 ASSERT(!object.is(value)); |
3293 | 3304 |
3294 if (!instr->transition().is_null()) { | 3305 if (!instr->transition().is_null()) { |
3295 __ mov(scratch, Operand(instr->transition())); | 3306 __ mov(scratch, Operand(instr->transition())); |
3296 __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); | 3307 __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); |
3297 } | 3308 } |
3298 | 3309 |
3299 // Do the store. | 3310 // Do the store. |
3311 HType type = instr->hydrogen()->value()->type(); | |
3312 SmiCheck check_needed = | |
3313 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
3300 if (instr->is_in_object()) { | 3314 if (instr->is_in_object()) { |
3301 __ str(value, FieldMemOperand(object, offset)); | 3315 __ str(value, FieldMemOperand(object, offset)); |
3302 if (instr->needs_write_barrier()) { | 3316 if (instr->hydrogen()->NeedsWriteBarrier()) { |
3303 // Update the write barrier for the object for in-object properties. | 3317 // Update the write barrier for the object for in-object properties. |
3304 __ RecordWriteField( | 3318 __ RecordWriteField( |
3305 object, offset, value, scratch, kLRHasBeenSaved, kSaveFPRegs); | 3319 object, offset, value, scratch, kLRHasBeenSaved, kSaveFPRegs, |
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
argument per line
| |
3320 EMIT_REMEMBERED_SET, check_needed); | |
3306 } | 3321 } |
3307 } else { | 3322 } else { |
3308 __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 3323 __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
3309 __ str(value, FieldMemOperand(scratch, offset)); | 3324 __ str(value, FieldMemOperand(scratch, offset)); |
3310 if (instr->needs_write_barrier()) { | 3325 if (instr->hydrogen()->NeedsWriteBarrier()) { |
3311 // Update the write barrier for the properties array. | 3326 // Update the write barrier for the properties array. |
3312 // object is used as a scratch register. | 3327 // object is used as a scratch register. |
3313 __ RecordWriteField( | 3328 __ RecordWriteField( |
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
argument per line
| |
3314 scratch, offset, value, object, kLRHasBeenSaved, kSaveFPRegs); | 3329 scratch, offset, value, object, kLRHasBeenSaved, kSaveFPRegs, |
3330 EMIT_REMEMBERED_SET, check_needed); | |
3315 } | 3331 } |
3316 } | 3332 } |
3317 } | 3333 } |
3318 | 3334 |
3319 | 3335 |
3320 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 3336 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
3321 ASSERT(ToRegister(instr->object()).is(r1)); | 3337 ASSERT(ToRegister(instr->object()).is(r1)); |
3322 ASSERT(ToRegister(instr->value()).is(r0)); | 3338 ASSERT(ToRegister(instr->value()).is(r0)); |
3323 | 3339 |
3324 // Name is always in r2. | 3340 // Name is always in r2. |
(...skipping 30 matching lines...) Expand all Loading... | |
3355 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 3371 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
3356 int offset = | 3372 int offset = |
3357 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; | 3373 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; |
3358 __ str(value, FieldMemOperand(elements, offset)); | 3374 __ str(value, FieldMemOperand(elements, offset)); |
3359 } else { | 3375 } else { |
3360 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | 3376 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
3361 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); | 3377 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
3362 } | 3378 } |
3363 | 3379 |
3364 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3380 if (instr->hydrogen()->NeedsWriteBarrier()) { |
3381 HType type = instr->hydrogen()->value()->type(); | |
3382 SmiCheck check_needed = | |
3383 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
3365 // Compute address of modified element and store it into key register. | 3384 // Compute address of modified element and store it into key register. |
3366 __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 3385 __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
3367 __ RecordWrite(elements, key, value, kLRHasBeenSaved, kSaveFPRegs); | 3386 __ RecordWrite(elements, key, value, kLRHasBeenSaved, kSaveFPRegs, |
Vyacheslav Egorov (Chromium)
2011/10/13 14:07:57
ditto
| |
3387 EMIT_REMEMBERED_SET, check_needed); | |
3368 } | 3388 } |
3369 } | 3389 } |
3370 | 3390 |
3371 | 3391 |
3372 void LCodeGen::DoStoreKeyedFastDoubleElement( | 3392 void LCodeGen::DoStoreKeyedFastDoubleElement( |
3373 LStoreKeyedFastDoubleElement* instr) { | 3393 LStoreKeyedFastDoubleElement* instr) { |
3374 DwVfpRegister value = ToDoubleRegister(instr->value()); | 3394 DwVfpRegister value = ToDoubleRegister(instr->value()); |
3375 Register elements = ToRegister(instr->elements()); | 3395 Register elements = ToRegister(instr->elements()); |
3376 Register key = no_reg; | 3396 Register key = no_reg; |
3377 Register scratch = scratch0(); | 3397 Register scratch = scratch0(); |
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4342 Register input = ToRegister(instr->InputAt(0)); | 4362 Register input = ToRegister(instr->InputAt(0)); |
4343 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 4363 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
4344 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 4364 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
4345 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 4365 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
4346 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 4366 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
4347 | 4367 |
4348 Condition final_branch_condition = EmitTypeofIs(true_label, | 4368 Condition final_branch_condition = EmitTypeofIs(true_label, |
4349 false_label, | 4369 false_label, |
4350 input, | 4370 input, |
4351 instr->type_literal()); | 4371 instr->type_literal()); |
4352 | 4372 if (final_branch_condition != kNoCondition) { |
4353 EmitBranch(true_block, false_block, final_branch_condition); | 4373 EmitBranch(true_block, false_block, final_branch_condition); |
4374 } | |
4354 } | 4375 } |
4355 | 4376 |
4356 | 4377 |
4357 Condition LCodeGen::EmitTypeofIs(Label* true_label, | 4378 Condition LCodeGen::EmitTypeofIs(Label* true_label, |
4358 Label* false_label, | 4379 Label* false_label, |
4359 Register input, | 4380 Register input, |
4360 Handle<String> type_name) { | 4381 Handle<String> type_name) { |
4361 Condition final_branch_condition = kNoCondition; | 4382 Condition final_branch_condition = kNoCondition; |
4362 Register scratch = scratch0(); | 4383 Register scratch = scratch0(); |
4363 if (type_name->Equals(heap()->number_symbol())) { | 4384 if (type_name->Equals(heap()->number_symbol())) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4413 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); | 4434 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); |
4414 __ b(lt, false_label); | 4435 __ b(lt, false_label); |
4415 __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 4436 __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
4416 __ b(gt, false_label); | 4437 __ b(gt, false_label); |
4417 // Check for undetectable objects => false. | 4438 // Check for undetectable objects => false. |
4418 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); | 4439 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); |
4419 __ tst(ip, Operand(1 << Map::kIsUndetectable)); | 4440 __ tst(ip, Operand(1 << Map::kIsUndetectable)); |
4420 final_branch_condition = eq; | 4441 final_branch_condition = eq; |
4421 | 4442 |
4422 } else { | 4443 } else { |
4423 final_branch_condition = ne; | |
4424 __ b(false_label); | 4444 __ b(false_label); |
4425 // A dead branch instruction will be generated after this point. | |
4426 } | 4445 } |
4427 | 4446 |
4428 return final_branch_condition; | 4447 return final_branch_condition; |
4429 } | 4448 } |
4430 | 4449 |
4431 | 4450 |
4432 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 4451 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
4433 Register temp1 = ToRegister(instr->TempAt(0)); | 4452 Register temp1 = ToRegister(instr->TempAt(0)); |
4434 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 4453 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
4435 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 4454 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4566 ASSERT(osr_pc_offset_ == -1); | 4585 ASSERT(osr_pc_offset_ == -1); |
4567 osr_pc_offset_ = masm()->pc_offset(); | 4586 osr_pc_offset_ = masm()->pc_offset(); |
4568 } | 4587 } |
4569 | 4588 |
4570 | 4589 |
4571 | 4590 |
4572 | 4591 |
4573 #undef __ | 4592 #undef __ |
4574 | 4593 |
4575 } } // namespace v8::internal | 4594 } } // namespace v8::internal |
OLD | NEW |