| 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 1626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1637 __ LoadRoot(a1, Heap::kNullValueRootIndex); | 1637 __ LoadRoot(a1, Heap::kNullValueRootIndex); |
| 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 |
| 1648 int depth = 1; |
| 1649 expr->BuildConstantProperties(isolate(), &depth); |
| 1647 Handle<FixedArray> constant_properties = expr->constant_properties(); | 1650 Handle<FixedArray> constant_properties = expr->constant_properties(); |
| 1648 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1651 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1649 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); | 1652 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); |
| 1650 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); | 1653 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); |
| 1651 __ li(a1, Operand(constant_properties)); | 1654 __ li(a1, Operand(constant_properties)); |
| 1652 int flags = expr->fast_elements() | 1655 int flags = expr->fast_elements() |
| 1653 ? ObjectLiteral::kFastElements | 1656 ? ObjectLiteral::kFastElements |
| 1654 : ObjectLiteral::kNoFlags; | 1657 : ObjectLiteral::kNoFlags; |
| 1655 flags |= expr->has_function() | 1658 flags |= expr->has_function() |
| 1656 ? ObjectLiteral::kHasFunction | 1659 ? ObjectLiteral::kHasFunction |
| 1657 : ObjectLiteral::kNoFlags; | 1660 : ObjectLiteral::kNoFlags; |
| 1658 __ li(a0, Operand(Smi::FromInt(flags))); | 1661 __ li(a0, Operand(Smi::FromInt(flags))); |
| 1659 int properties_count = constant_properties->length() / 2; | 1662 int properties_count = constant_properties->length() / 2; |
| 1660 if ((FLAG_track_double_fields && expr->may_store_doubles()) || | 1663 if ((FLAG_track_double_fields && expr->may_store_doubles()) || |
| 1661 expr->depth() > 1 || Serializer::enabled() || | 1664 depth > 1 || Serializer::enabled() || |
| 1662 flags != ObjectLiteral::kFastElements || | 1665 flags != ObjectLiteral::kFastElements || |
| 1663 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { | 1666 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { |
| 1664 __ Push(a3, a2, a1, a0); | 1667 __ Push(a3, a2, a1, a0); |
| 1665 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); | 1668 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); |
| 1666 } else { | 1669 } else { |
| 1667 FastCloneShallowObjectStub stub(properties_count); | 1670 FastCloneShallowObjectStub stub(properties_count); |
| 1668 __ CallStub(&stub); | 1671 __ CallStub(&stub); |
| 1669 } | 1672 } |
| 1670 | 1673 |
| 1671 // If result_saved is true the result is on top of the stack. If | 1674 // 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... |
| 1770 context()->PlugTOS(); | 1773 context()->PlugTOS(); |
| 1771 } else { | 1774 } else { |
| 1772 context()->Plug(v0); | 1775 context()->Plug(v0); |
| 1773 } | 1776 } |
| 1774 } | 1777 } |
| 1775 | 1778 |
| 1776 | 1779 |
| 1777 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1780 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1778 Comment cmnt(masm_, "[ ArrayLiteral"); | 1781 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 1779 | 1782 |
| 1783 int depth = 1; |
| 1784 expr->BuildConstantElements(isolate(), &depth); |
| 1780 ZoneList<Expression*>* subexprs = expr->values(); | 1785 ZoneList<Expression*>* subexprs = expr->values(); |
| 1781 int length = subexprs->length(); | 1786 int length = subexprs->length(); |
| 1782 | 1787 |
| 1783 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1788 Handle<FixedArray> constant_elements = expr->constant_elements(); |
| 1784 ASSERT_EQ(2, constant_elements->length()); | 1789 ASSERT_EQ(2, constant_elements->length()); |
| 1785 ElementsKind constant_elements_kind = | 1790 ElementsKind constant_elements_kind = |
| 1786 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value()); | 1791 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value()); |
| 1787 bool has_fast_elements = | 1792 bool has_fast_elements = |
| 1788 IsFastObjectElementsKind(constant_elements_kind); | 1793 IsFastObjectElementsKind(constant_elements_kind); |
| 1789 Handle<FixedArrayBase> constant_elements_values( | 1794 Handle<FixedArrayBase> constant_elements_values( |
| 1790 FixedArrayBase::cast(constant_elements->get(1))); | 1795 FixedArrayBase::cast(constant_elements->get(1))); |
| 1791 | 1796 |
| 1792 __ mov(a0, result_register()); | 1797 __ mov(a0, result_register()); |
| 1793 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1798 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1794 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); | 1799 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); |
| 1795 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); | 1800 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); |
| 1796 __ li(a1, Operand(constant_elements)); | 1801 __ li(a1, Operand(constant_elements)); |
| 1797 if (has_fast_elements && constant_elements_values->map() == | 1802 if (has_fast_elements && constant_elements_values->map() == |
| 1798 isolate()->heap()->fixed_cow_array_map()) { | 1803 isolate()->heap()->fixed_cow_array_map()) { |
| 1799 FastCloneShallowArrayStub stub( | 1804 FastCloneShallowArrayStub stub( |
| 1800 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, | 1805 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, |
| 1801 DONT_TRACK_ALLOCATION_SITE, | 1806 DONT_TRACK_ALLOCATION_SITE, |
| 1802 length); | 1807 length); |
| 1803 __ CallStub(&stub); | 1808 __ CallStub(&stub); |
| 1804 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), | 1809 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), |
| 1805 1, a1, a2); | 1810 1, a1, a2); |
| 1806 } else if (expr->depth() > 1 || | 1811 } else if (depth > 1 || Serializer::enabled() || |
| 1807 Serializer::enabled() || | |
| 1808 length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 1812 length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
| 1809 __ Push(a3, a2, a1); | 1813 __ Push(a3, a2, a1); |
| 1810 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); | 1814 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); |
| 1811 } else { | 1815 } else { |
| 1812 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || | 1816 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || |
| 1813 FLAG_smi_only_arrays); | 1817 FLAG_smi_only_arrays); |
| 1814 FastCloneShallowArrayStub::Mode mode = | 1818 FastCloneShallowArrayStub::Mode mode = |
| 1815 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; | 1819 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; |
| 1816 AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites | 1820 AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites |
| 1817 ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE; | 1821 ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE; |
| (...skipping 2613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4431 } | 4435 } |
| 4432 | 4436 |
| 4433 // We need a second deoptimization point after loading the value | 4437 // We need a second deoptimization point after loading the value |
| 4434 // in case evaluating the property load my have a side effect. | 4438 // in case evaluating the property load my have a side effect. |
| 4435 if (assign_type == VARIABLE) { | 4439 if (assign_type == VARIABLE) { |
| 4436 PrepareForBailout(expr->expression(), TOS_REG); | 4440 PrepareForBailout(expr->expression(), TOS_REG); |
| 4437 } else { | 4441 } else { |
| 4438 PrepareForBailoutForId(prop->LoadId(), TOS_REG); | 4442 PrepareForBailoutForId(prop->LoadId(), TOS_REG); |
| 4439 } | 4443 } |
| 4440 | 4444 |
| 4441 // Call ToNumber only if operand is not a smi. | 4445 // Inline smi case if we are in a loop. |
| 4442 Label no_conversion; | 4446 Label stub_call, done; |
| 4447 JumpPatchSite patch_site(masm_); |
| 4448 |
| 4449 int count_value = expr->op() == Token::INC ? 1 : -1; |
| 4450 __ mov(a0, v0); |
| 4443 if (ShouldInlineSmiCase(expr->op())) { | 4451 if (ShouldInlineSmiCase(expr->op())) { |
| 4444 __ JumpIfSmi(v0, &no_conversion); | 4452 Label slow; |
| 4453 patch_site.EmitJumpIfNotSmi(v0, &slow); |
| 4454 |
| 4455 // Save result for postfix expressions. |
| 4456 if (expr->is_postfix()) { |
| 4457 if (!context()->IsEffect()) { |
| 4458 // Save the result on the stack. If we have a named or keyed property |
| 4459 // we store the result under the receiver that is currently on top |
| 4460 // of the stack. |
| 4461 switch (assign_type) { |
| 4462 case VARIABLE: |
| 4463 __ push(v0); |
| 4464 break; |
| 4465 case NAMED_PROPERTY: |
| 4466 __ sw(v0, MemOperand(sp, kPointerSize)); |
| 4467 break; |
| 4468 case KEYED_PROPERTY: |
| 4469 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); |
| 4470 break; |
| 4471 } |
| 4472 } |
| 4473 } |
| 4474 |
| 4475 Register scratch1 = a1; |
| 4476 Register scratch2 = t0; |
| 4477 __ li(scratch1, Operand(Smi::FromInt(count_value))); |
| 4478 __ AdduAndCheckForOverflow(v0, v0, scratch1, scratch2); |
| 4479 __ BranchOnNoOverflow(&done, scratch2); |
| 4480 // Call stub. Undo operation first. |
| 4481 __ Move(v0, a0); |
| 4482 __ jmp(&stub_call); |
| 4483 __ bind(&slow); |
| 4445 } | 4484 } |
| 4446 __ mov(a0, v0); | |
| 4447 ToNumberStub convert_stub; | 4485 ToNumberStub convert_stub; |
| 4448 __ CallStub(&convert_stub); | 4486 __ CallStub(&convert_stub); |
| 4449 __ bind(&no_conversion); | |
| 4450 | 4487 |
| 4451 // Save result for postfix expressions. | 4488 // Save result for postfix expressions. |
| 4452 if (expr->is_postfix()) { | 4489 if (expr->is_postfix()) { |
| 4453 if (!context()->IsEffect()) { | 4490 if (!context()->IsEffect()) { |
| 4454 // Save the result on the stack. If we have a named or keyed property | 4491 // Save the result on the stack. If we have a named or keyed property |
| 4455 // we store the result under the receiver that is currently on top | 4492 // we store the result under the receiver that is currently on top |
| 4456 // of the stack. | 4493 // of the stack. |
| 4457 switch (assign_type) { | 4494 switch (assign_type) { |
| 4458 case VARIABLE: | 4495 case VARIABLE: |
| 4459 __ push(v0); | 4496 __ push(v0); |
| 4460 break; | 4497 break; |
| 4461 case NAMED_PROPERTY: | 4498 case NAMED_PROPERTY: |
| 4462 __ sw(v0, MemOperand(sp, kPointerSize)); | 4499 __ sw(v0, MemOperand(sp, kPointerSize)); |
| 4463 break; | 4500 break; |
| 4464 case KEYED_PROPERTY: | 4501 case KEYED_PROPERTY: |
| 4465 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); | 4502 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); |
| 4466 break; | 4503 break; |
| 4467 } | 4504 } |
| 4468 } | 4505 } |
| 4469 } | 4506 } |
| 4470 __ mov(a0, result_register()); | |
| 4471 | 4507 |
| 4472 // Inline smi case if we are in a loop. | 4508 __ bind(&stub_call); |
| 4473 Label stub_call, done; | 4509 __ mov(a1, v0); |
| 4474 JumpPatchSite patch_site(masm_); | |
| 4475 | |
| 4476 int count_value = expr->op() == Token::INC ? 1 : -1; | |
| 4477 if (ShouldInlineSmiCase(expr->op())) { | |
| 4478 __ li(a1, Operand(Smi::FromInt(count_value))); | |
| 4479 __ AdduAndCheckForOverflow(v0, a0, a1, t0); | |
| 4480 __ BranchOnOverflow(&stub_call, t0); // Do stub on overflow. | |
| 4481 | |
| 4482 // We could eliminate this smi check if we split the code at | |
| 4483 // the first smi check before calling ToNumber. | |
| 4484 patch_site.EmitJumpIfSmi(v0, &done); | |
| 4485 __ bind(&stub_call); | |
| 4486 } | |
| 4487 __ mov(a1, a0); | |
| 4488 __ li(a0, Operand(Smi::FromInt(count_value))); | 4510 __ li(a0, Operand(Smi::FromInt(count_value))); |
| 4489 | 4511 |
| 4490 // Record position before stub call. | 4512 // Record position before stub call. |
| 4491 SetSourcePosition(expr->position()); | 4513 SetSourcePosition(expr->position()); |
| 4492 | 4514 |
| 4493 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); | 4515 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); |
| 4494 CallIC(stub.GetCode(isolate()), | 4516 CallIC(stub.GetCode(isolate()), |
| 4495 RelocInfo::CODE_TARGET, | 4517 RelocInfo::CODE_TARGET, |
| 4496 expr->CountBinOpFeedbackId()); | 4518 expr->CountBinOpFeedbackId()); |
| 4497 patch_site.EmitPatchInfo(); | 4519 patch_site.EmitPatchInfo(); |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4994 Assembler::target_address_at(pc_immediate_load_address)) == | 5016 Assembler::target_address_at(pc_immediate_load_address)) == |
| 4995 reinterpret_cast<uint32_t>( | 5017 reinterpret_cast<uint32_t>( |
| 4996 isolate->builtins()->OsrAfterStackCheck()->entry())); | 5018 isolate->builtins()->OsrAfterStackCheck()->entry())); |
| 4997 return OSR_AFTER_STACK_CHECK; | 5019 return OSR_AFTER_STACK_CHECK; |
| 4998 } | 5020 } |
| 4999 | 5021 |
| 5000 | 5022 |
| 5001 } } // namespace v8::internal | 5023 } } // namespace v8::internal |
| 5002 | 5024 |
| 5003 #endif // V8_TARGET_ARCH_MIPS | 5025 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |