| 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 1627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1638 __ push(a1); | 1638 __ push(a1); |
| 1639 } else { | 1639 } else { |
| 1640 VisitForStackValue(expression); | 1640 VisitForStackValue(expression); |
| 1641 } | 1641 } |
| 1642 } | 1642 } |
| 1643 | 1643 |
| 1644 | 1644 |
| 1645 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 1645 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
| 1646 Comment cmnt(masm_, "[ ObjectLiteral"); | 1646 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 1647 | 1647 |
| 1648 int depth = 1; | 1648 expr->BuildConstantProperties(isolate()); |
| 1649 expr->BuildConstantProperties(isolate(), &depth); | |
| 1650 Handle<FixedArray> constant_properties = expr->constant_properties(); | 1649 Handle<FixedArray> constant_properties = expr->constant_properties(); |
| 1651 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1650 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1652 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); | 1651 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); |
| 1653 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); | 1652 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); |
| 1654 __ li(a1, Operand(constant_properties)); | 1653 __ li(a1, Operand(constant_properties)); |
| 1655 int flags = expr->fast_elements() | 1654 int flags = expr->fast_elements() |
| 1656 ? ObjectLiteral::kFastElements | 1655 ? ObjectLiteral::kFastElements |
| 1657 : ObjectLiteral::kNoFlags; | 1656 : ObjectLiteral::kNoFlags; |
| 1658 flags |= expr->has_function() | 1657 flags |= expr->has_function() |
| 1659 ? ObjectLiteral::kHasFunction | 1658 ? ObjectLiteral::kHasFunction |
| 1660 : ObjectLiteral::kNoFlags; | 1659 : ObjectLiteral::kNoFlags; |
| 1661 __ li(a0, Operand(Smi::FromInt(flags))); | 1660 __ li(a0, Operand(Smi::FromInt(flags))); |
| 1662 int properties_count = constant_properties->length() / 2; | 1661 int properties_count = constant_properties->length() / 2; |
| 1663 if ((FLAG_track_double_fields && expr->may_store_doubles()) || | 1662 if ((FLAG_track_double_fields && expr->may_store_doubles()) || |
| 1664 depth > 1 || Serializer::enabled() || | 1663 expr->depth() > 1 || Serializer::enabled() || |
| 1665 flags != ObjectLiteral::kFastElements || | 1664 flags != ObjectLiteral::kFastElements || |
| 1666 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { | 1665 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { |
| 1667 __ Push(a3, a2, a1, a0); | 1666 __ Push(a3, a2, a1, a0); |
| 1668 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); | 1667 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); |
| 1669 } else { | 1668 } else { |
| 1670 FastCloneShallowObjectStub stub(properties_count); | 1669 FastCloneShallowObjectStub stub(properties_count); |
| 1671 __ CallStub(&stub); | 1670 __ CallStub(&stub); |
| 1672 } | 1671 } |
| 1673 | 1672 |
| 1674 // If result_saved is true the result is on top of the stack. If | 1673 // If result_saved is true the result is on top of the stack. If |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1773 context()->PlugTOS(); | 1772 context()->PlugTOS(); |
| 1774 } else { | 1773 } else { |
| 1775 context()->Plug(v0); | 1774 context()->Plug(v0); |
| 1776 } | 1775 } |
| 1777 } | 1776 } |
| 1778 | 1777 |
| 1779 | 1778 |
| 1780 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1779 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1781 Comment cmnt(masm_, "[ ArrayLiteral"); | 1780 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 1782 | 1781 |
| 1783 int depth = 1; | 1782 expr->BuildConstantElements(isolate()); |
| 1784 expr->BuildConstantElements(isolate(), &depth); | |
| 1785 ZoneList<Expression*>* subexprs = expr->values(); | 1783 ZoneList<Expression*>* subexprs = expr->values(); |
| 1786 int length = subexprs->length(); | 1784 int length = subexprs->length(); |
| 1787 | 1785 |
| 1788 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1786 Handle<FixedArray> constant_elements = expr->constant_elements(); |
| 1789 ASSERT_EQ(2, constant_elements->length()); | 1787 ASSERT_EQ(2, constant_elements->length()); |
| 1790 ElementsKind constant_elements_kind = | 1788 ElementsKind constant_elements_kind = |
| 1791 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value()); | 1789 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value()); |
| 1792 bool has_fast_elements = | 1790 bool has_fast_elements = |
| 1793 IsFastObjectElementsKind(constant_elements_kind); | 1791 IsFastObjectElementsKind(constant_elements_kind); |
| 1794 Handle<FixedArrayBase> constant_elements_values( | 1792 Handle<FixedArrayBase> constant_elements_values( |
| 1795 FixedArrayBase::cast(constant_elements->get(1))); | 1793 FixedArrayBase::cast(constant_elements->get(1))); |
| 1796 | 1794 |
| 1797 __ mov(a0, result_register()); | 1795 __ mov(a0, result_register()); |
| 1798 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1796 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1799 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); | 1797 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); |
| 1800 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); | 1798 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); |
| 1801 __ li(a1, Operand(constant_elements)); | 1799 __ li(a1, Operand(constant_elements)); |
| 1802 if (has_fast_elements && constant_elements_values->map() == | 1800 if (has_fast_elements && constant_elements_values->map() == |
| 1803 isolate()->heap()->fixed_cow_array_map()) { | 1801 isolate()->heap()->fixed_cow_array_map()) { |
| 1804 FastCloneShallowArrayStub stub( | 1802 FastCloneShallowArrayStub stub( |
| 1805 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, | 1803 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, |
| 1806 DONT_TRACK_ALLOCATION_SITE, | 1804 DONT_TRACK_ALLOCATION_SITE, |
| 1807 length); | 1805 length); |
| 1808 __ CallStub(&stub); | 1806 __ CallStub(&stub); |
| 1809 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), | 1807 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), |
| 1810 1, a1, a2); | 1808 1, a1, a2); |
| 1811 } else if (depth > 1 || Serializer::enabled() || | 1809 } else if (expr->depth() > 1 || Serializer::enabled() || |
| 1812 length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 1810 length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
| 1813 __ Push(a3, a2, a1); | 1811 __ Push(a3, a2, a1); |
| 1814 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); | 1812 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); |
| 1815 } else { | 1813 } else { |
| 1816 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || | 1814 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || |
| 1817 FLAG_smi_only_arrays); | 1815 FLAG_smi_only_arrays); |
| 1818 FastCloneShallowArrayStub::Mode mode = | 1816 FastCloneShallowArrayStub::Mode mode = |
| 1819 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; | 1817 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; |
| 1820 AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites | 1818 AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites |
| 1821 ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE; | 1819 ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE; |
| (...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2909 VisitForAccumulatorValue(args->at(0)); | 2907 VisitForAccumulatorValue(args->at(0)); |
| 2910 | 2908 |
| 2911 Label materialize_true, materialize_false; | 2909 Label materialize_true, materialize_false; |
| 2912 Label* if_true = NULL; | 2910 Label* if_true = NULL; |
| 2913 Label* if_false = NULL; | 2911 Label* if_false = NULL; |
| 2914 Label* fall_through = NULL; | 2912 Label* fall_through = NULL; |
| 2915 context()->PrepareTest(&materialize_true, &materialize_false, | 2913 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2916 &if_true, &if_false, &fall_through); | 2914 &if_true, &if_false, &fall_through); |
| 2917 | 2915 |
| 2918 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 2916 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2919 __ And(t0, v0, Operand(kSmiTagMask)); | 2917 __ SmiTst(v0, t0); |
| 2920 Split(eq, t0, Operand(zero_reg), if_true, if_false, fall_through); | 2918 Split(eq, t0, Operand(zero_reg), if_true, if_false, fall_through); |
| 2921 | 2919 |
| 2922 context()->Plug(if_true, if_false); | 2920 context()->Plug(if_true, if_false); |
| 2923 } | 2921 } |
| 2924 | 2922 |
| 2925 | 2923 |
| 2926 void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { | 2924 void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { |
| 2927 ZoneList<Expression*>* args = expr->arguments(); | 2925 ZoneList<Expression*>* args = expr->arguments(); |
| 2928 ASSERT(args->length() == 1); | 2926 ASSERT(args->length() == 1); |
| 2929 | 2927 |
| 2930 VisitForAccumulatorValue(args->at(0)); | 2928 VisitForAccumulatorValue(args->at(0)); |
| 2931 | 2929 |
| 2932 Label materialize_true, materialize_false; | 2930 Label materialize_true, materialize_false; |
| 2933 Label* if_true = NULL; | 2931 Label* if_true = NULL; |
| 2934 Label* if_false = NULL; | 2932 Label* if_false = NULL; |
| 2935 Label* fall_through = NULL; | 2933 Label* fall_through = NULL; |
| 2936 context()->PrepareTest(&materialize_true, &materialize_false, | 2934 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2937 &if_true, &if_false, &fall_through); | 2935 &if_true, &if_false, &fall_through); |
| 2938 | 2936 |
| 2939 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 2937 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2940 __ And(at, v0, Operand(kSmiTagMask | 0x80000000)); | 2938 __ NonNegativeSmiTst(v0, at); |
| 2941 Split(eq, at, Operand(zero_reg), if_true, if_false, fall_through); | 2939 Split(eq, at, Operand(zero_reg), if_true, if_false, fall_through); |
| 2942 | 2940 |
| 2943 context()->Plug(if_true, if_false); | 2941 context()->Plug(if_true, if_false); |
| 2944 } | 2942 } |
| 2945 | 2943 |
| 2946 | 2944 |
| 2947 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) { | 2945 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) { |
| 2948 ZoneList<Expression*>* args = expr->arguments(); | 2946 ZoneList<Expression*>* args = expr->arguments(); |
| 2949 ASSERT(args->length() == 1); | 2947 ASSERT(args->length() == 1); |
| 2950 | 2948 |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3373 VisitForStackValue(args->at(2)); | 3371 VisitForStackValue(args->at(2)); |
| 3374 __ CallRuntime(Runtime::kLog, 2); | 3372 __ CallRuntime(Runtime::kLog, 2); |
| 3375 } | 3373 } |
| 3376 | 3374 |
| 3377 // Finally, we're expected to leave a value on the top of the stack. | 3375 // Finally, we're expected to leave a value on the top of the stack. |
| 3378 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 3376 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); |
| 3379 context()->Plug(v0); | 3377 context()->Plug(v0); |
| 3380 } | 3378 } |
| 3381 | 3379 |
| 3382 | 3380 |
| 3383 void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) { | |
| 3384 ASSERT(expr->arguments()->length() == 0); | |
| 3385 Label slow_allocate_heapnumber; | |
| 3386 Label heapnumber_allocated; | |
| 3387 | |
| 3388 // Save the new heap number in callee-saved register s0, since | |
| 3389 // we call out to external C code below. | |
| 3390 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex); | |
| 3391 __ AllocateHeapNumber(s0, a1, a2, t6, &slow_allocate_heapnumber); | |
| 3392 __ jmp(&heapnumber_allocated); | |
| 3393 | |
| 3394 __ bind(&slow_allocate_heapnumber); | |
| 3395 | |
| 3396 // Allocate a heap number. | |
| 3397 __ CallRuntime(Runtime::kNumberAlloc, 0); | |
| 3398 __ mov(s0, v0); // Save result in s0, so it is saved thru CFunc call. | |
| 3399 | |
| 3400 __ bind(&heapnumber_allocated); | |
| 3401 | |
| 3402 // Convert 32 random bits in v0 to 0.(32 random bits) in a double | |
| 3403 // by computing: | |
| 3404 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). | |
| 3405 __ PrepareCallCFunction(1, a0); | |
| 3406 __ lw(a0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); | |
| 3407 __ lw(a0, FieldMemOperand(a0, GlobalObject::kNativeContextOffset)); | |
| 3408 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); | |
| 3409 | |
| 3410 // 0x41300000 is the top half of 1.0 x 2^20 as a double. | |
| 3411 __ li(a1, Operand(0x41300000)); | |
| 3412 // Move 0x41300000xxxxxxxx (x = random bits in v0) to FPU. | |
| 3413 __ Move(f12, v0, a1); | |
| 3414 // Move 0x4130000000000000 to FPU. | |
| 3415 __ Move(f14, zero_reg, a1); | |
| 3416 // Subtract and store the result in the heap number. | |
| 3417 __ sub_d(f0, f12, f14); | |
| 3418 __ sdc1(f0, FieldMemOperand(s0, HeapNumber::kValueOffset)); | |
| 3419 __ mov(v0, s0); | |
| 3420 | |
| 3421 context()->Plug(v0); | |
| 3422 } | |
| 3423 | |
| 3424 | |
| 3425 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { | 3381 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
| 3426 // Load the arguments on the stack and call the stub. | 3382 // Load the arguments on the stack and call the stub. |
| 3427 SubStringStub stub; | 3383 SubStringStub stub; |
| 3428 ZoneList<Expression*>* args = expr->arguments(); | 3384 ZoneList<Expression*>* args = expr->arguments(); |
| 3429 ASSERT(args->length() == 3); | 3385 ASSERT(args->length() == 3); |
| 3430 VisitForStackValue(args->at(0)); | 3386 VisitForStackValue(args->at(0)); |
| 3431 VisitForStackValue(args->at(1)); | 3387 VisitForStackValue(args->at(1)); |
| 3432 VisitForStackValue(args->at(2)); | 3388 VisitForStackValue(args->at(2)); |
| 3433 __ CallStub(&stub); | 3389 __ CallStub(&stub); |
| 3434 context()->Plug(v0); | 3390 context()->Plug(v0); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3509 __ jmp(&done); | 3465 __ jmp(&done); |
| 3510 } | 3466 } |
| 3511 | 3467 |
| 3512 __ bind(¬_date_object); | 3468 __ bind(¬_date_object); |
| 3513 __ CallRuntime(Runtime::kThrowNotDateError, 0); | 3469 __ CallRuntime(Runtime::kThrowNotDateError, 0); |
| 3514 __ bind(&done); | 3470 __ bind(&done); |
| 3515 context()->Plug(v0); | 3471 context()->Plug(v0); |
| 3516 } | 3472 } |
| 3517 | 3473 |
| 3518 | 3474 |
| 3519 void FullCodeGenerator::EmitSeqStringSetCharCheck(Register string, | |
| 3520 Register index, | |
| 3521 Register value, | |
| 3522 uint32_t encoding_mask) { | |
| 3523 __ And(at, index, Operand(kSmiTagMask)); | |
| 3524 __ Check(eq, kNonSmiIndex, at, Operand(zero_reg)); | |
| 3525 __ And(at, value, Operand(kSmiTagMask)); | |
| 3526 __ Check(eq, kNonSmiValue, at, Operand(zero_reg)); | |
| 3527 | |
| 3528 __ lw(at, FieldMemOperand(string, String::kLengthOffset)); | |
| 3529 __ Check(lt, kIndexIsTooLarge, index, Operand(at)); | |
| 3530 | |
| 3531 __ Check(ge, kIndexIsNegative, index, Operand(zero_reg)); | |
| 3532 | |
| 3533 __ lw(at, FieldMemOperand(string, HeapObject::kMapOffset)); | |
| 3534 __ lbu(at, FieldMemOperand(at, Map::kInstanceTypeOffset)); | |
| 3535 | |
| 3536 __ And(at, at, Operand(kStringRepresentationMask | kStringEncodingMask)); | |
| 3537 __ Subu(at, at, Operand(encoding_mask)); | |
| 3538 __ Check(eq, kUnexpectedStringType, at, Operand(zero_reg)); | |
| 3539 } | |
| 3540 | |
| 3541 | |
| 3542 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { | 3475 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { |
| 3543 ZoneList<Expression*>* args = expr->arguments(); | 3476 ZoneList<Expression*>* args = expr->arguments(); |
| 3544 ASSERT_EQ(3, args->length()); | 3477 ASSERT_EQ(3, args->length()); |
| 3545 | 3478 |
| 3546 Register string = v0; | 3479 Register string = v0; |
| 3547 Register index = a1; | 3480 Register index = a1; |
| 3548 Register value = a2; | 3481 Register value = a2; |
| 3549 | 3482 |
| 3550 VisitForStackValue(args->at(1)); // index | 3483 VisitForStackValue(args->at(1)); // index |
| 3551 VisitForStackValue(args->at(2)); // value | 3484 VisitForStackValue(args->at(2)); // value |
| 3485 VisitForAccumulatorValue(args->at(0)); // string |
| 3552 __ Pop(index, value); | 3486 __ Pop(index, value); |
| 3553 VisitForAccumulatorValue(args->at(0)); // string | |
| 3554 | 3487 |
| 3555 if (FLAG_debug_code) { | 3488 if (FLAG_debug_code) { |
| 3489 __ SmiTst(value, at); |
| 3490 __ ThrowIf(ne, kNonSmiValue, at, Operand(zero_reg)); |
| 3491 __ SmiTst(index, at); |
| 3492 __ ThrowIf(ne, kNonSmiIndex, at, Operand(zero_reg)); |
| 3493 __ SmiUntag(index, index); |
| 3556 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; | 3494 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; |
| 3557 EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); | 3495 Register scratch = t5; |
| 3496 __ EmitSeqStringSetCharCheck( |
| 3497 string, index, value, scratch, one_byte_seq_type); |
| 3498 __ SmiTag(index, index); |
| 3558 } | 3499 } |
| 3559 | 3500 |
| 3560 __ SmiUntag(value, value); | 3501 __ SmiUntag(value, value); |
| 3561 __ Addu(at, | 3502 __ Addu(at, |
| 3562 string, | 3503 string, |
| 3563 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); | 3504 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); |
| 3564 __ SmiUntag(index); | 3505 __ SmiUntag(index); |
| 3565 __ Addu(at, at, index); | 3506 __ Addu(at, at, index); |
| 3566 __ sb(value, MemOperand(at)); | 3507 __ sb(value, MemOperand(at)); |
| 3567 context()->Plug(string); | 3508 context()->Plug(string); |
| 3568 } | 3509 } |
| 3569 | 3510 |
| 3570 | 3511 |
| 3571 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { | 3512 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { |
| 3572 ZoneList<Expression*>* args = expr->arguments(); | 3513 ZoneList<Expression*>* args = expr->arguments(); |
| 3573 ASSERT_EQ(3, args->length()); | 3514 ASSERT_EQ(3, args->length()); |
| 3574 | 3515 |
| 3575 Register string = v0; | 3516 Register string = v0; |
| 3576 Register index = a1; | 3517 Register index = a1; |
| 3577 Register value = a2; | 3518 Register value = a2; |
| 3578 | 3519 |
| 3579 VisitForStackValue(args->at(1)); // index | 3520 VisitForStackValue(args->at(1)); // index |
| 3580 VisitForStackValue(args->at(2)); // value | 3521 VisitForStackValue(args->at(2)); // value |
| 3522 VisitForAccumulatorValue(args->at(0)); // string |
| 3581 __ Pop(index, value); | 3523 __ Pop(index, value); |
| 3582 VisitForAccumulatorValue(args->at(0)); // string | |
| 3583 | 3524 |
| 3584 if (FLAG_debug_code) { | 3525 if (FLAG_debug_code) { |
| 3526 __ SmiTst(value, at); |
| 3527 __ ThrowIf(ne, kNonSmiValue, at, Operand(zero_reg)); |
| 3528 __ SmiTst(index, at); |
| 3529 __ ThrowIf(ne, kNonSmiIndex, at, Operand(zero_reg)); |
| 3530 __ SmiUntag(index, index); |
| 3585 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; | 3531 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; |
| 3586 EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); | 3532 Register scratch = t5; |
| 3533 __ EmitSeqStringSetCharCheck( |
| 3534 string, index, value, scratch, two_byte_seq_type); |
| 3535 __ SmiTag(index, index); |
| 3587 } | 3536 } |
| 3588 | 3537 |
| 3589 __ SmiUntag(value, value); | 3538 __ SmiUntag(value, value); |
| 3590 __ Addu(at, | 3539 __ Addu(at, |
| 3591 string, | 3540 string, |
| 3592 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | 3541 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
| 3593 __ Addu(at, at, index); | 3542 __ Addu(at, at, index); |
| 3594 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 3543 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
| 3595 __ sh(value, MemOperand(at)); | 3544 __ sh(value, MemOperand(at)); |
| 3596 context()->Plug(string); | 3545 context()->Plug(string); |
| (...skipping 1419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5016 Assembler::target_address_at(pc_immediate_load_address)) == | 4965 Assembler::target_address_at(pc_immediate_load_address)) == |
| 5017 reinterpret_cast<uint32_t>( | 4966 reinterpret_cast<uint32_t>( |
| 5018 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4967 isolate->builtins()->OsrAfterStackCheck()->entry())); |
| 5019 return OSR_AFTER_STACK_CHECK; | 4968 return OSR_AFTER_STACK_CHECK; |
| 5020 } | 4969 } |
| 5021 | 4970 |
| 5022 | 4971 |
| 5023 } } // namespace v8::internal | 4972 } } // namespace v8::internal |
| 5024 | 4973 |
| 5025 #endif // V8_TARGET_ARCH_MIPS | 4974 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |