| 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(object, |
| 3305 object, offset, value, scratch, kLRHasBeenSaved, kSaveFPRegs); | 3319 offset, |
| 3320 value, |
| 3321 scratch, |
| 3322 kLRHasBeenSaved, |
| 3323 kSaveFPRegs, |
| 3324 EMIT_REMEMBERED_SET, |
| 3325 check_needed); |
| 3306 } | 3326 } |
| 3307 } else { | 3327 } else { |
| 3308 __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 3328 __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 3309 __ str(value, FieldMemOperand(scratch, offset)); | 3329 __ str(value, FieldMemOperand(scratch, offset)); |
| 3310 if (instr->needs_write_barrier()) { | 3330 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 3311 // Update the write barrier for the properties array. | 3331 // Update the write barrier for the properties array. |
| 3312 // object is used as a scratch register. | 3332 // object is used as a scratch register. |
| 3313 __ RecordWriteField( | 3333 __ RecordWriteField(scratch, |
| 3314 scratch, offset, value, object, kLRHasBeenSaved, kSaveFPRegs); | 3334 offset, |
| 3335 value, |
| 3336 object, |
| 3337 kLRHasBeenSaved, |
| 3338 kSaveFPRegs, |
| 3339 EMIT_REMEMBERED_SET, |
| 3340 check_needed); |
| 3315 } | 3341 } |
| 3316 } | 3342 } |
| 3317 } | 3343 } |
| 3318 | 3344 |
| 3319 | 3345 |
| 3320 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 3346 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
| 3321 ASSERT(ToRegister(instr->object()).is(r1)); | 3347 ASSERT(ToRegister(instr->object()).is(r1)); |
| 3322 ASSERT(ToRegister(instr->value()).is(r0)); | 3348 ASSERT(ToRegister(instr->value()).is(r0)); |
| 3323 | 3349 |
| 3324 // Name is always in r2. | 3350 // Name is always in r2. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3355 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 3381 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
| 3356 int offset = | 3382 int offset = |
| 3357 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; | 3383 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; |
| 3358 __ str(value, FieldMemOperand(elements, offset)); | 3384 __ str(value, FieldMemOperand(elements, offset)); |
| 3359 } else { | 3385 } else { |
| 3360 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | 3386 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
| 3361 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); | 3387 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
| 3362 } | 3388 } |
| 3363 | 3389 |
| 3364 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3390 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 3391 HType type = instr->hydrogen()->value()->type(); |
| 3392 SmiCheck check_needed = |
| 3393 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 3365 // Compute address of modified element and store it into key register. | 3394 // Compute address of modified element and store it into key register. |
| 3366 __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 3395 __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 3367 __ RecordWrite(elements, key, value, kLRHasBeenSaved, kSaveFPRegs); | 3396 __ RecordWrite(elements, |
| 3397 key, |
| 3398 value, |
| 3399 kLRHasBeenSaved, |
| 3400 kSaveFPRegs, |
| 3401 EMIT_REMEMBERED_SET, |
| 3402 check_needed); |
| 3368 } | 3403 } |
| 3369 } | 3404 } |
| 3370 | 3405 |
| 3371 | 3406 |
| 3372 void LCodeGen::DoStoreKeyedFastDoubleElement( | 3407 void LCodeGen::DoStoreKeyedFastDoubleElement( |
| 3373 LStoreKeyedFastDoubleElement* instr) { | 3408 LStoreKeyedFastDoubleElement* instr) { |
| 3374 DwVfpRegister value = ToDoubleRegister(instr->value()); | 3409 DwVfpRegister value = ToDoubleRegister(instr->value()); |
| 3375 Register elements = ToRegister(instr->elements()); | 3410 Register elements = ToRegister(instr->elements()); |
| 3376 Register key = no_reg; | 3411 Register key = no_reg; |
| 3377 Register scratch = scratch0(); | 3412 Register scratch = scratch0(); |
| (...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4342 Register input = ToRegister(instr->InputAt(0)); | 4377 Register input = ToRegister(instr->InputAt(0)); |
| 4343 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 4378 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 4344 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 4379 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 4345 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 4380 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| 4346 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 4381 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 4347 | 4382 |
| 4348 Condition final_branch_condition = EmitTypeofIs(true_label, | 4383 Condition final_branch_condition = EmitTypeofIs(true_label, |
| 4349 false_label, | 4384 false_label, |
| 4350 input, | 4385 input, |
| 4351 instr->type_literal()); | 4386 instr->type_literal()); |
| 4352 | 4387 if (final_branch_condition != kNoCondition) { |
| 4353 EmitBranch(true_block, false_block, final_branch_condition); | 4388 EmitBranch(true_block, false_block, final_branch_condition); |
| 4389 } |
| 4354 } | 4390 } |
| 4355 | 4391 |
| 4356 | 4392 |
| 4357 Condition LCodeGen::EmitTypeofIs(Label* true_label, | 4393 Condition LCodeGen::EmitTypeofIs(Label* true_label, |
| 4358 Label* false_label, | 4394 Label* false_label, |
| 4359 Register input, | 4395 Register input, |
| 4360 Handle<String> type_name) { | 4396 Handle<String> type_name) { |
| 4361 Condition final_branch_condition = kNoCondition; | 4397 Condition final_branch_condition = kNoCondition; |
| 4362 Register scratch = scratch0(); | 4398 Register scratch = scratch0(); |
| 4363 if (type_name->Equals(heap()->number_symbol())) { | 4399 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); | 4449 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); |
| 4414 __ b(lt, false_label); | 4450 __ b(lt, false_label); |
| 4415 __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 4451 __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
| 4416 __ b(gt, false_label); | 4452 __ b(gt, false_label); |
| 4417 // Check for undetectable objects => false. | 4453 // Check for undetectable objects => false. |
| 4418 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); | 4454 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); |
| 4419 __ tst(ip, Operand(1 << Map::kIsUndetectable)); | 4455 __ tst(ip, Operand(1 << Map::kIsUndetectable)); |
| 4420 final_branch_condition = eq; | 4456 final_branch_condition = eq; |
| 4421 | 4457 |
| 4422 } else { | 4458 } else { |
| 4423 final_branch_condition = ne; | |
| 4424 __ b(false_label); | 4459 __ b(false_label); |
| 4425 // A dead branch instruction will be generated after this point. | |
| 4426 } | 4460 } |
| 4427 | 4461 |
| 4428 return final_branch_condition; | 4462 return final_branch_condition; |
| 4429 } | 4463 } |
| 4430 | 4464 |
| 4431 | 4465 |
| 4432 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 4466 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
| 4433 Register temp1 = ToRegister(instr->TempAt(0)); | 4467 Register temp1 = ToRegister(instr->TempAt(0)); |
| 4434 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 4468 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 4435 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 4469 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); | 4600 ASSERT(osr_pc_offset_ == -1); |
| 4567 osr_pc_offset_ = masm()->pc_offset(); | 4601 osr_pc_offset_ = masm()->pc_offset(); |
| 4568 } | 4602 } |
| 4569 | 4603 |
| 4570 | 4604 |
| 4571 | 4605 |
| 4572 | 4606 |
| 4573 #undef __ | 4607 #undef __ |
| 4574 | 4608 |
| 4575 } } // namespace v8::internal | 4609 } } // namespace v8::internal |
| OLD | NEW |