Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Side by Side Diff: src/arm/codegen-arm.cc

Issue 6597029: [Isolates] Merge r 6300:6500 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/codegen-arm-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 1570 matching lines...) Expand 10 before | Expand all | Expand 10 after
1581 break; 1581 break;
1582 } 1582 }
1583 1583
1584 default: 1584 default:
1585 UNREACHABLE(); 1585 UNREACHABLE();
1586 break; 1586 break;
1587 } 1587 }
1588 } 1588 }
1589 1589
1590 1590
1591 void CodeGenerator::Comparison(Condition cc, 1591 void CodeGenerator::Comparison(Condition cond,
1592 Expression* left, 1592 Expression* left,
1593 Expression* right, 1593 Expression* right,
1594 bool strict) { 1594 bool strict) {
1595 VirtualFrame::RegisterAllocationScope scope(this); 1595 VirtualFrame::RegisterAllocationScope scope(this);
1596 1596
1597 if (left != NULL) Load(left); 1597 if (left != NULL) Load(left);
1598 if (right != NULL) Load(right); 1598 if (right != NULL) Load(right);
1599 1599
1600 // sp[0] : y 1600 // sp[0] : y
1601 // sp[1] : x 1601 // sp[1] : x
1602 // result : cc register 1602 // result : cc register
1603 1603
1604 // Strict only makes sense for equality comparisons. 1604 // Strict only makes sense for equality comparisons.
1605 ASSERT(!strict || cc == eq); 1605 ASSERT(!strict || cond == eq);
1606 1606
1607 Register lhs; 1607 Register lhs;
1608 Register rhs; 1608 Register rhs;
1609 1609
1610 bool lhs_is_smi; 1610 bool lhs_is_smi;
1611 bool rhs_is_smi; 1611 bool rhs_is_smi;
1612 1612
1613 // We load the top two stack positions into registers chosen by the virtual 1613 // We load the top two stack positions into registers chosen by the virtual
1614 // frame. This should keep the register shuffling to a minimum. 1614 // frame. This should keep the register shuffling to a minimum.
1615 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order. 1615 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order.
1616 if (cc == gt || cc == le) { 1616 if (cond == gt || cond == le) {
1617 cc = ReverseCondition(cc); 1617 cond = ReverseCondition(cond);
1618 lhs_is_smi = frame_->KnownSmiAt(0); 1618 lhs_is_smi = frame_->KnownSmiAt(0);
1619 rhs_is_smi = frame_->KnownSmiAt(1); 1619 rhs_is_smi = frame_->KnownSmiAt(1);
1620 lhs = frame_->PopToRegister(); 1620 lhs = frame_->PopToRegister();
1621 rhs = frame_->PopToRegister(lhs); // Don't pop to the same register again! 1621 rhs = frame_->PopToRegister(lhs); // Don't pop to the same register again!
1622 } else { 1622 } else {
1623 rhs_is_smi = frame_->KnownSmiAt(0); 1623 rhs_is_smi = frame_->KnownSmiAt(0);
1624 lhs_is_smi = frame_->KnownSmiAt(1); 1624 lhs_is_smi = frame_->KnownSmiAt(1);
1625 rhs = frame_->PopToRegister(); 1625 rhs = frame_->PopToRegister();
1626 lhs = frame_->PopToRegister(rhs); // Don't pop to the same register again! 1626 lhs = frame_->PopToRegister(rhs); // Don't pop to the same register again!
1627 } 1627 }
(...skipping 19 matching lines...) Expand all
1647 __ orr(scratch, lhs, Operand(rhs)); 1647 __ orr(scratch, lhs, Operand(rhs));
1648 smi_test_reg = scratch; 1648 smi_test_reg = scratch;
1649 } 1649 }
1650 __ tst(smi_test_reg, Operand(kSmiTagMask)); 1650 __ tst(smi_test_reg, Operand(kSmiTagMask));
1651 JumpTarget smi; 1651 JumpTarget smi;
1652 smi.Branch(eq); 1652 smi.Branch(eq);
1653 1653
1654 // Perform non-smi comparison by stub. 1654 // Perform non-smi comparison by stub.
1655 // CompareStub takes arguments in r0 and r1, returns <0, >0 or 0 in r0. 1655 // CompareStub takes arguments in r0 and r1, returns <0, >0 or 0 in r0.
1656 // We call with 0 args because there are 0 on the stack. 1656 // We call with 0 args because there are 0 on the stack.
1657 CompareStub stub(cc, strict, NO_SMI_COMPARE_IN_STUB, lhs, rhs); 1657 CompareStub stub(cond, strict, NO_SMI_COMPARE_IN_STUB, lhs, rhs);
1658 frame_->CallStub(&stub, 0); 1658 frame_->CallStub(&stub, 0);
1659 __ cmp(r0, Operand(0, RelocInfo::NONE)); 1659 __ cmp(r0, Operand(0, RelocInfo::NONE));
1660 exit.Jump(); 1660 exit.Jump();
1661 1661
1662 smi.Bind(); 1662 smi.Bind();
1663 } 1663 }
1664 1664
1665 // Do smi comparisons by pointer comparison. 1665 // Do smi comparisons by pointer comparison.
1666 __ cmp(lhs, Operand(rhs)); 1666 __ cmp(lhs, Operand(rhs));
1667 1667
1668 exit.Bind(); 1668 exit.Bind();
1669 cc_reg_ = cc; 1669 cc_reg_ = cond;
1670 } 1670 }
1671 1671
1672 1672
1673 // Call the function on the stack with the given arguments. 1673 // Call the function on the stack with the given arguments.
1674 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, 1674 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
1675 CallFunctionFlags flags, 1675 CallFunctionFlags flags,
1676 int position) { 1676 int position) {
1677 // Push the arguments ("left-to-right") on the stack. 1677 // Push the arguments ("left-to-right") on the stack.
1678 int arg_count = args->length(); 1678 int arg_count = args->length();
1679 for (int i = 0; i < arg_count; i++) { 1679 for (int i = 0; i < arg_count; i++) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1754 Label build_args; 1754 Label build_args;
1755 // Get rid of the arguments object probe. 1755 // Get rid of the arguments object probe.
1756 frame_->Drop(); 1756 frame_->Drop();
1757 // Stack now has 3 elements on it. 1757 // Stack now has 3 elements on it.
1758 // Contents of stack at this point: 1758 // Contents of stack at this point:
1759 // sp[0]: receiver - in the receiver_reg register. 1759 // sp[0]: receiver - in the receiver_reg register.
1760 // sp[1]: applicand.apply 1760 // sp[1]: applicand.apply
1761 // sp[2]: applicand. 1761 // sp[2]: applicand.
1762 1762
1763 // Check that the receiver really is a JavaScript object. 1763 // Check that the receiver really is a JavaScript object.
1764 __ BranchOnSmi(receiver_reg, &build_args); 1764 __ JumpIfSmi(receiver_reg, &build_args);
1765 // We allow all JSObjects including JSFunctions. As long as 1765 // We allow all JSObjects including JSFunctions. As long as
1766 // JS_FUNCTION_TYPE is the last instance type and it is right 1766 // JS_FUNCTION_TYPE is the last instance type and it is right
1767 // after LAST_JS_OBJECT_TYPE, we do not have to check the upper 1767 // after LAST_JS_OBJECT_TYPE, we do not have to check the upper
1768 // bound. 1768 // bound.
1769 STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); 1769 STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
1770 STATIC_ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1); 1770 STATIC_ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
1771 __ CompareObjectType(receiver_reg, r2, r3, FIRST_JS_OBJECT_TYPE); 1771 __ CompareObjectType(receiver_reg, r2, r3, FIRST_JS_OBJECT_TYPE);
1772 __ b(lt, &build_args); 1772 __ b(lt, &build_args);
1773 1773
1774 // Check that applicand.apply is Function.prototype.apply. 1774 // Check that applicand.apply is Function.prototype.apply.
1775 __ ldr(r0, MemOperand(sp, kPointerSize)); 1775 __ ldr(r0, MemOperand(sp, kPointerSize));
1776 __ BranchOnSmi(r0, &build_args); 1776 __ JumpIfSmi(r0, &build_args);
1777 __ CompareObjectType(r0, r1, r2, JS_FUNCTION_TYPE); 1777 __ CompareObjectType(r0, r1, r2, JS_FUNCTION_TYPE);
1778 __ b(ne, &build_args); 1778 __ b(ne, &build_args);
1779 Handle<Code> apply_code( 1779 Handle<Code> apply_code(
1780 Isolate::Current()->builtins()->builtin(Builtins::FunctionApply)); 1780 Isolate::Current()->builtins()->builtin(Builtins::FunctionApply));
1781 __ ldr(r1, FieldMemOperand(r0, JSFunction::kCodeEntryOffset)); 1781 __ ldr(r1, FieldMemOperand(r0, JSFunction::kCodeEntryOffset));
1782 __ sub(r1, r1, Operand(Code::kHeaderSize - kHeapObjectTag)); 1782 __ sub(r1, r1, Operand(Code::kHeaderSize - kHeapObjectTag));
1783 __ cmp(r1, Operand(apply_code)); 1783 __ cmp(r1, Operand(apply_code));
1784 __ b(ne, &build_args); 1784 __ b(ne, &build_args);
1785 1785
1786 // Check that applicand is a function. 1786 // Check that applicand is a function.
1787 __ ldr(r1, MemOperand(sp, 2 * kPointerSize)); 1787 __ ldr(r1, MemOperand(sp, 2 * kPointerSize));
1788 __ BranchOnSmi(r1, &build_args); 1788 __ JumpIfSmi(r1, &build_args);
1789 __ CompareObjectType(r1, r2, r3, JS_FUNCTION_TYPE); 1789 __ CompareObjectType(r1, r2, r3, JS_FUNCTION_TYPE);
1790 __ b(ne, &build_args); 1790 __ b(ne, &build_args);
1791 1791
1792 // Copy the arguments to this function possibly from the 1792 // Copy the arguments to this function possibly from the
1793 // adaptor frame below it. 1793 // adaptor frame below it.
1794 Label invoke, adapted; 1794 Label invoke, adapted;
1795 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 1795 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
1796 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); 1796 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
1797 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 1797 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1798 __ b(eq, &adapted); 1798 __ b(eq, &adapted);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1878 // sp[0]: result 1878 // sp[0]: result
1879 __ bind(&done); 1879 __ bind(&done);
1880 1880
1881 // Restore the context register after a call. 1881 // Restore the context register after a call.
1882 __ ldr(cp, frame_->Context()); 1882 __ ldr(cp, frame_->Context());
1883 } 1883 }
1884 1884
1885 1885
1886 void CodeGenerator::Branch(bool if_true, JumpTarget* target) { 1886 void CodeGenerator::Branch(bool if_true, JumpTarget* target) {
1887 ASSERT(has_cc()); 1887 ASSERT(has_cc());
1888 Condition cc = if_true ? cc_reg_ : NegateCondition(cc_reg_); 1888 Condition cond = if_true ? cc_reg_ : NegateCondition(cc_reg_);
1889 target->Branch(cc); 1889 target->Branch(cond);
1890 cc_reg_ = al; 1890 cc_reg_ = al;
1891 } 1891 }
1892 1892
1893 1893
1894 void CodeGenerator::CheckStack() { 1894 void CodeGenerator::CheckStack() {
1895 frame_->SpillAll(); 1895 frame_->SpillAll();
1896 Comment cmnt(masm_, "[ check stack"); 1896 Comment cmnt(masm_, "[ check stack");
1897 __ LoadRoot(ip, Heap::kStackLimitRootIndex); 1897 __ LoadRoot(ip, Heap::kStackLimitRootIndex);
1898 masm_->cmp(sp, Operand(ip)); 1898 masm_->cmp(sp, Operand(ip));
1899 StackCheckStub stub; 1899 StackCheckStub stub;
(...skipping 2715 matching lines...) Expand 10 before | Expand all | Expand 10 after
4615 // Get base and exponent to registers. 4615 // Get base and exponent to registers.
4616 Register exponent = frame_->PopToRegister(); 4616 Register exponent = frame_->PopToRegister();
4617 Register base = frame_->PopToRegister(exponent); 4617 Register base = frame_->PopToRegister(exponent);
4618 Register heap_number_map = no_reg; 4618 Register heap_number_map = no_reg;
4619 4619
4620 // Set the frame for the runtime jump target. The code below jumps to the 4620 // Set the frame for the runtime jump target. The code below jumps to the
4621 // jump target label so the frame needs to be established before that. 4621 // jump target label so the frame needs to be established before that.
4622 ASSERT(runtime.entry_frame() == NULL); 4622 ASSERT(runtime.entry_frame() == NULL);
4623 runtime.set_entry_frame(frame_); 4623 runtime.set_entry_frame(frame_);
4624 4624
4625 __ BranchOnNotSmi(exponent, &exponent_nonsmi); 4625 __ JumpIfNotSmi(exponent, &exponent_nonsmi);
4626 __ BranchOnNotSmi(base, &base_nonsmi); 4626 __ JumpIfNotSmi(base, &base_nonsmi);
4627 4627
4628 heap_number_map = r6; 4628 heap_number_map = r6;
4629 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); 4629 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
4630 4630
4631 // Exponent is a smi and base is a smi. Get the smi value into vfp register 4631 // Exponent is a smi and base is a smi. Get the smi value into vfp register
4632 // d1. 4632 // d1.
4633 __ SmiToDoubleVFPRegister(base, d1, scratch1, s0); 4633 __ SmiToDoubleVFPRegister(base, d1, scratch1, s0);
4634 __ b(&powi); 4634 __ b(&powi);
4635 4635
4636 __ bind(&base_nonsmi); 4636 __ bind(&base_nonsmi);
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after
5569 DeferredSwapElements* deferred = 5569 DeferredSwapElements* deferred =
5570 new DeferredSwapElements(object, index1, index2); 5570 new DeferredSwapElements(object, index1, index2);
5571 5571
5572 // Fetch the map and check if array is in fast case. 5572 // Fetch the map and check if array is in fast case.
5573 // Check that object doesn't require security checks and 5573 // Check that object doesn't require security checks and
5574 // has no indexed interceptor. 5574 // has no indexed interceptor.
5575 __ CompareObjectType(object, tmp1, tmp2, FIRST_JS_OBJECT_TYPE); 5575 __ CompareObjectType(object, tmp1, tmp2, FIRST_JS_OBJECT_TYPE);
5576 deferred->Branch(lt); 5576 deferred->Branch(lt);
5577 __ ldrb(tmp2, FieldMemOperand(tmp1, Map::kBitFieldOffset)); 5577 __ ldrb(tmp2, FieldMemOperand(tmp1, Map::kBitFieldOffset));
5578 __ tst(tmp2, Operand(KeyedLoadIC::kSlowCaseBitFieldMask)); 5578 __ tst(tmp2, Operand(KeyedLoadIC::kSlowCaseBitFieldMask));
5579 deferred->Branch(nz); 5579 deferred->Branch(ne);
5580 5580
5581 // Check the object's elements are in fast case and writable. 5581 // Check the object's elements are in fast case and writable.
5582 __ ldr(tmp1, FieldMemOperand(object, JSObject::kElementsOffset)); 5582 __ ldr(tmp1, FieldMemOperand(object, JSObject::kElementsOffset));
5583 __ ldr(tmp2, FieldMemOperand(tmp1, HeapObject::kMapOffset)); 5583 __ ldr(tmp2, FieldMemOperand(tmp1, HeapObject::kMapOffset));
5584 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); 5584 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
5585 __ cmp(tmp2, ip); 5585 __ cmp(tmp2, ip);
5586 deferred->Branch(ne); 5586 deferred->Branch(ne);
5587 5587
5588 // Smi-tagging is equivalent to multiplying by 2. 5588 // Smi-tagging is equivalent to multiplying by 2.
5589 STATIC_ASSERT(kSmiTag == 0); 5589 STATIC_ASSERT(kSmiTag == 0);
5590 STATIC_ASSERT(kSmiTagSize == 1); 5590 STATIC_ASSERT(kSmiTagSize == 1);
5591 5591
5592 // Check that both indices are smis. 5592 // Check that both indices are smis.
5593 __ mov(tmp2, index1); 5593 __ mov(tmp2, index1);
5594 __ orr(tmp2, tmp2, index2); 5594 __ orr(tmp2, tmp2, index2);
5595 __ tst(tmp2, Operand(kSmiTagMask)); 5595 __ tst(tmp2, Operand(kSmiTagMask));
5596 deferred->Branch(nz); 5596 deferred->Branch(ne);
5597 5597
5598 // Check that both indices are valid. 5598 // Check that both indices are valid.
5599 __ ldr(tmp2, FieldMemOperand(object, JSArray::kLengthOffset)); 5599 __ ldr(tmp2, FieldMemOperand(object, JSArray::kLengthOffset));
5600 __ cmp(tmp2, index1); 5600 __ cmp(tmp2, index1);
5601 __ cmp(tmp2, index2, hi); 5601 __ cmp(tmp2, index2, hi);
5602 deferred->Branch(ls); 5602 deferred->Branch(ls);
5603 5603
5604 // Bring the offsets into the fixed array in tmp1 into index1 and 5604 // Bring the offsets into the fixed array in tmp1 into index1 and
5605 // index2. 5605 // index2.
5606 __ mov(tmp2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 5606 __ mov(tmp2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
5847 5847
5848 } else if (variable != NULL) { 5848 } else if (variable != NULL) {
5849 Slot* slot = variable->AsSlot(); 5849 Slot* slot = variable->AsSlot();
5850 if (variable->is_global()) { 5850 if (variable->is_global()) {
5851 LoadGlobal(); 5851 LoadGlobal();
5852 frame_->EmitPush(Operand(variable->name())); 5852 frame_->EmitPush(Operand(variable->name()));
5853 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2); 5853 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2);
5854 frame_->EmitPush(r0); 5854 frame_->EmitPush(r0);
5855 5855
5856 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 5856 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
5857 // lookup the context holding the named variable 5857 // Delete from the context holding the named variable.
5858 frame_->EmitPush(cp); 5858 frame_->EmitPush(cp);
5859 frame_->EmitPush(Operand(variable->name())); 5859 frame_->EmitPush(Operand(variable->name()));
5860 frame_->CallRuntime(Runtime::kLookupContext, 2); 5860 frame_->CallRuntime(Runtime::kDeleteContextSlot, 2);
5861 // r0: context
5862 frame_->EmitPush(r0);
5863 frame_->EmitPush(Operand(variable->name()));
5864 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2);
5865 frame_->EmitPush(r0); 5861 frame_->EmitPush(r0);
5866 5862
5867 } else { 5863 } else {
5868 // Default: Result of deleting non-global, not dynamically 5864 // Default: Result of deleting non-global, not dynamically
5869 // introduced variables is false. 5865 // introduced variables is false.
5870 frame_->EmitPushRoot(Heap::kFalseValueRootIndex); 5866 frame_->EmitPushRoot(Heap::kFalseValueRootIndex);
5871 } 5867 }
5872 5868
5873 } else { 5869 } else {
5874 // Default: Result of deleting expressions is true. 5870 // Default: Result of deleting expressions is true.
(...skipping 1502 matching lines...) Expand 10 before | Expand all | Expand 10 after
7377 specialized_on_rhs_ ? "_ConstantRhs" : "", 7373 specialized_on_rhs_ ? "_ConstantRhs" : "",
7378 BinaryOpIC::GetName(runtime_operands_type_)); 7374 BinaryOpIC::GetName(runtime_operands_type_));
7379 return name_; 7375 return name_;
7380 } 7376 }
7381 7377
7382 #undef __ 7378 #undef __
7383 7379
7384 } } // namespace v8::internal 7380 } } // namespace v8::internal
7385 7381
7386 #endif // V8_TARGET_ARCH_ARM 7382 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/codegen-arm-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698