OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1899 __ ubfx(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount); | 1899 __ ubfx(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount); |
1900 } | 1900 } |
1901 | 1901 |
1902 | 1902 |
1903 void LCodeGen::DoValueOf(LValueOf* instr) { | 1903 void LCodeGen::DoValueOf(LValueOf* instr) { |
1904 Register input = ToRegister(instr->value()); | 1904 Register input = ToRegister(instr->value()); |
1905 Register result = ToRegister(instr->result()); | 1905 Register result = ToRegister(instr->result()); |
1906 Register map = ToRegister(instr->temp()); | 1906 Register map = ToRegister(instr->temp()); |
1907 Label done; | 1907 Label done; |
1908 | 1908 |
1909 // If the object is a smi return the object. | 1909 if (!instr->hydrogen()->value()->IsHeapObject()) { |
1910 __ SmiTst(input); | 1910 // If the object is a smi return the object. |
1911 __ Move(result, input, eq); | 1911 __ SmiTst(input); |
1912 __ b(eq, &done); | 1912 __ Move(result, input, eq); |
1913 __ b(eq, &done); | |
1914 } | |
1913 | 1915 |
1914 // If the object is not a value type, return the object. | 1916 // If the object is not a value type, return the object. |
1915 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); | 1917 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); |
1916 __ Move(result, input, ne); | 1918 __ Move(result, input, ne); |
1917 __ b(ne, &done); | 1919 __ b(ne, &done); |
1918 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset)); | 1920 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset)); |
1919 | 1921 |
1920 __ bind(&done); | 1922 __ bind(&done); |
1921 } | 1923 } |
1922 | 1924 |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2454 | 2456 |
2455 Condition true_cond = | 2457 Condition true_cond = |
2456 EmitIsObject(reg, temp1, false_label, true_label); | 2458 EmitIsObject(reg, temp1, false_label, true_label); |
2457 | 2459 |
2458 EmitBranch(true_block, false_block, true_cond); | 2460 EmitBranch(true_block, false_block, true_cond); |
2459 } | 2461 } |
2460 | 2462 |
2461 | 2463 |
2462 Condition LCodeGen::EmitIsString(Register input, | 2464 Condition LCodeGen::EmitIsString(Register input, |
2463 Register temp1, | 2465 Register temp1, |
2464 Label* is_not_string) { | 2466 Label* is_not_string, |
2465 __ JumpIfSmi(input, is_not_string); | 2467 SmiCheck check_needed = INLINE_SMI_CHECK) { |
2468 if (check_needed == INLINE_SMI_CHECK) { | |
2469 __ JumpIfSmi(input, is_not_string); | |
2470 } | |
2466 __ CompareObjectType(input, temp1, temp1, FIRST_NONSTRING_TYPE); | 2471 __ CompareObjectType(input, temp1, temp1, FIRST_NONSTRING_TYPE); |
2467 | 2472 |
2468 return lt; | 2473 return lt; |
2469 } | 2474 } |
2470 | 2475 |
2471 | 2476 |
2472 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { | 2477 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { |
2473 Register reg = ToRegister(instr->value()); | 2478 Register reg = ToRegister(instr->value()); |
2474 Register temp1 = ToRegister(instr->temp()); | 2479 Register temp1 = ToRegister(instr->temp()); |
2475 | 2480 |
2476 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 2481 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
2477 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 2482 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
2478 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 2483 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
2479 | 2484 |
2485 SmiCheck check_needed = | |
2486 instr->hydrogen()->value()->IsHeapObject() | |
2487 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
2480 Condition true_cond = | 2488 Condition true_cond = |
2481 EmitIsString(reg, temp1, false_label); | 2489 EmitIsString(reg, temp1, false_label, check_needed); |
2482 | 2490 |
2483 EmitBranch(true_block, false_block, true_cond); | 2491 EmitBranch(true_block, false_block, true_cond); |
2484 } | 2492 } |
2485 | 2493 |
2486 | 2494 |
2487 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { | 2495 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { |
2488 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 2496 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
2489 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 2497 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
2490 | 2498 |
2491 Register input_reg = EmitLoadRegister(instr->value(), ip); | 2499 Register input_reg = EmitLoadRegister(instr->value(), ip); |
2492 __ SmiTst(input_reg); | 2500 __ SmiTst(input_reg); |
2493 EmitBranch(true_block, false_block, eq); | 2501 EmitBranch(true_block, false_block, eq); |
2494 } | 2502 } |
2495 | 2503 |
2496 | 2504 |
2497 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { | 2505 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { |
2498 Register input = ToRegister(instr->value()); | 2506 Register input = ToRegister(instr->value()); |
2499 Register temp = ToRegister(instr->temp()); | 2507 Register temp = ToRegister(instr->temp()); |
2500 | 2508 |
2501 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 2509 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
2502 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 2510 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
2503 | 2511 |
2504 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); | 2512 if (!instr->hydrogen()->value()->IsHeapObject()) { |
2513 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); | |
2514 } | |
2505 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset)); | 2515 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset)); |
2506 __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); | 2516 __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); |
2507 __ tst(temp, Operand(1 << Map::kIsUndetectable)); | 2517 __ tst(temp, Operand(1 << Map::kIsUndetectable)); |
2508 EmitBranch(true_block, false_block, ne); | 2518 EmitBranch(true_block, false_block, ne); |
2509 } | 2519 } |
2510 | 2520 |
2511 | 2521 |
2512 static Condition ComputeCompareCondition(Token::Value op) { | 2522 static Condition ComputeCompareCondition(Token::Value op) { |
2513 switch (op) { | 2523 switch (op) { |
2514 case Token::EQ_STRICT: | 2524 case Token::EQ_STRICT: |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2567 | 2577 |
2568 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { | 2578 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { |
2569 Register scratch = scratch0(); | 2579 Register scratch = scratch0(); |
2570 Register input = ToRegister(instr->value()); | 2580 Register input = ToRegister(instr->value()); |
2571 | 2581 |
2572 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 2582 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
2573 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 2583 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
2574 | 2584 |
2575 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 2585 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
2576 | 2586 |
2577 __ JumpIfSmi(input, false_label); | 2587 if (!instr->hydrogen()->value()->IsHeapObject()) { |
2588 __ JumpIfSmi(input, false_label); | |
2589 } | |
2578 | 2590 |
2579 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); | 2591 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); |
2580 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); | 2592 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); |
2581 } | 2593 } |
2582 | 2594 |
2583 | 2595 |
2584 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { | 2596 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { |
2585 Register input = ToRegister(instr->value()); | 2597 Register input = ToRegister(instr->value()); |
2586 Register result = ToRegister(instr->result()); | 2598 Register result = ToRegister(instr->result()); |
2587 | 2599 |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3012 __ cmp(scratch, ip); | 3024 __ cmp(scratch, ip); |
3013 if (instr->hydrogen()->DeoptimizesOnHole()) { | 3025 if (instr->hydrogen()->DeoptimizesOnHole()) { |
3014 DeoptimizeIf(eq, instr->environment()); | 3026 DeoptimizeIf(eq, instr->environment()); |
3015 } else { | 3027 } else { |
3016 __ b(ne, &skip_assignment); | 3028 __ b(ne, &skip_assignment); |
3017 } | 3029 } |
3018 } | 3030 } |
3019 | 3031 |
3020 __ str(value, target); | 3032 __ str(value, target); |
3021 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3033 if (instr->hydrogen()->NeedsWriteBarrier()) { |
3022 HType type = instr->hydrogen()->value()->type(); | |
3023 SmiCheck check_needed = | 3034 SmiCheck check_needed = |
3024 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 3035 instr->hydrogen()->value()->IsHeapObject() |
3036 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
3025 __ RecordWriteContextSlot(context, | 3037 __ RecordWriteContextSlot(context, |
3026 target.offset(), | 3038 target.offset(), |
3027 value, | 3039 value, |
3028 scratch, | 3040 scratch, |
3029 GetLinkRegisterState(), | 3041 GetLinkRegisterState(), |
3030 kSaveFPRegs, | 3042 kSaveFPRegs, |
3031 EMIT_REMEMBERED_SET, | 3043 EMIT_REMEMBERED_SET, |
3032 check_needed); | 3044 check_needed); |
3033 } | 3045 } |
3034 | 3046 |
(...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4256 GetLinkRegisterState(), | 4268 GetLinkRegisterState(), |
4257 kSaveFPRegs, | 4269 kSaveFPRegs, |
4258 OMIT_REMEMBERED_SET, | 4270 OMIT_REMEMBERED_SET, |
4259 OMIT_SMI_CHECK); | 4271 OMIT_SMI_CHECK); |
4260 } | 4272 } |
4261 } | 4273 } |
4262 | 4274 |
4263 // Do the store. | 4275 // Do the store. |
4264 Register value = ToRegister(instr->value()); | 4276 Register value = ToRegister(instr->value()); |
4265 ASSERT(!object.is(value)); | 4277 ASSERT(!object.is(value)); |
4266 HType type = instr->hydrogen()->value()->type(); | |
4267 SmiCheck check_needed = | 4278 SmiCheck check_needed = |
4268 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4279 !instr->hydrogen()->value()->IsHeapObject() |
ulan
2013/06/20 07:49:11
Negate the condition to make it consistent with th
| |
4280 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; | |
4269 if (access.IsInobject()) { | 4281 if (access.IsInobject()) { |
4270 __ str(value, FieldMemOperand(object, offset)); | 4282 __ str(value, FieldMemOperand(object, offset)); |
4271 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4283 if (instr->hydrogen()->NeedsWriteBarrier()) { |
4272 // Update the write barrier for the object for in-object properties. | 4284 // Update the write barrier for the object for in-object properties. |
4273 __ RecordWriteField(object, | 4285 __ RecordWriteField(object, |
4274 offset, | 4286 offset, |
4275 value, | 4287 value, |
4276 scratch, | 4288 scratch, |
4277 GetLinkRegisterState(), | 4289 GetLinkRegisterState(), |
4278 kSaveFPRegs, | 4290 kSaveFPRegs, |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4467 if (instr->hydrogen()->key()->representation().IsSmi()) { | 4479 if (instr->hydrogen()->key()->representation().IsSmi()) { |
4468 __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); | 4480 __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); |
4469 } else { | 4481 } else { |
4470 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | 4482 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
4471 } | 4483 } |
4472 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | 4484 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); |
4473 } | 4485 } |
4474 __ str(value, FieldMemOperand(store_base, offset)); | 4486 __ str(value, FieldMemOperand(store_base, offset)); |
4475 | 4487 |
4476 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4488 if (instr->hydrogen()->NeedsWriteBarrier()) { |
4477 HType type = instr->hydrogen()->value()->type(); | |
4478 SmiCheck check_needed = | 4489 SmiCheck check_needed = |
4479 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4490 instr->hydrogen()->value()->IsHeapObject() |
4491 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
4480 // Compute address of modified element and store it into key register. | 4492 // Compute address of modified element and store it into key register. |
4481 __ add(key, store_base, Operand(offset - kHeapObjectTag)); | 4493 __ add(key, store_base, Operand(offset - kHeapObjectTag)); |
4482 __ RecordWrite(elements, | 4494 __ RecordWrite(elements, |
4483 key, | 4495 key, |
4484 value, | 4496 value, |
4485 GetLinkRegisterState(), | 4497 GetLinkRegisterState(), |
4486 kSaveFPRegs, | 4498 kSaveFPRegs, |
4487 EMIT_REMEMBERED_SET, | 4499 EMIT_REMEMBERED_SET, |
4488 check_needed); | 4500 check_needed); |
4489 } | 4501 } |
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5880 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5892 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
5881 __ ldr(result, FieldMemOperand(scratch, | 5893 __ ldr(result, FieldMemOperand(scratch, |
5882 FixedArray::kHeaderSize - kPointerSize)); | 5894 FixedArray::kHeaderSize - kPointerSize)); |
5883 __ bind(&done); | 5895 __ bind(&done); |
5884 } | 5896 } |
5885 | 5897 |
5886 | 5898 |
5887 #undef __ | 5899 #undef __ |
5888 | 5900 |
5889 } } // namespace v8::internal | 5901 } } // namespace v8::internal |
OLD | NEW |