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 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 |