OLD | NEW |
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 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 frame_->EmitPush(r0); | 199 frame_->EmitPush(r0); |
200 if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 200 if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
201 FastNewContextStub stub(heap_slots); | 201 FastNewContextStub stub(heap_slots); |
202 frame_->CallStub(&stub, 1); | 202 frame_->CallStub(&stub, 1); |
203 } else { | 203 } else { |
204 frame_->CallRuntime(Runtime::kNewContext, 1); | 204 frame_->CallRuntime(Runtime::kNewContext, 1); |
205 } | 205 } |
206 | 206 |
207 #ifdef DEBUG | 207 #ifdef DEBUG |
208 JumpTarget verified_true; | 208 JumpTarget verified_true; |
209 __ cmp(r0, Operand(cp)); | 209 __ cmp(r0, cp); |
210 verified_true.Branch(eq); | 210 verified_true.Branch(eq); |
211 __ stop("NewContext: r0 is expected to be the same as cp"); | 211 __ stop("NewContext: r0 is expected to be the same as cp"); |
212 verified_true.Bind(); | 212 verified_true.Bind(); |
213 #endif | 213 #endif |
214 // Update context local. | 214 // Update context local. |
215 __ str(cp, frame_->Context()); | 215 __ str(cp, frame_->Context()); |
216 } | 216 } |
217 | 217 |
218 // TODO(1241774): Improve this code: | 218 // TODO(1241774): Improve this code: |
219 // 1) only needed if we have a context | 219 // 1) only needed if we have a context |
(...skipping 1765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1985 Comment cmnt(masm_, "[ WithEnterStatement"); | 1985 Comment cmnt(masm_, "[ WithEnterStatement"); |
1986 CodeForStatementPosition(node); | 1986 CodeForStatementPosition(node); |
1987 LoadAndSpill(node->expression()); | 1987 LoadAndSpill(node->expression()); |
1988 if (node->is_catch_block()) { | 1988 if (node->is_catch_block()) { |
1989 frame_->CallRuntime(Runtime::kPushCatchContext, 1); | 1989 frame_->CallRuntime(Runtime::kPushCatchContext, 1); |
1990 } else { | 1990 } else { |
1991 frame_->CallRuntime(Runtime::kPushContext, 1); | 1991 frame_->CallRuntime(Runtime::kPushContext, 1); |
1992 } | 1992 } |
1993 #ifdef DEBUG | 1993 #ifdef DEBUG |
1994 JumpTarget verified_true; | 1994 JumpTarget verified_true; |
1995 __ cmp(r0, Operand(cp)); | 1995 __ cmp(r0, cp); |
1996 verified_true.Branch(eq); | 1996 verified_true.Branch(eq); |
1997 __ stop("PushContext: r0 is expected to be the same as cp"); | 1997 __ stop("PushContext: r0 is expected to be the same as cp"); |
1998 verified_true.Bind(); | 1998 verified_true.Bind(); |
1999 #endif | 1999 #endif |
2000 // Update context local. | 2000 // Update context local. |
2001 __ str(cp, frame_->Context()); | 2001 __ str(cp, frame_->Context()); |
2002 ASSERT(frame_->height() == original_height); | 2002 ASSERT(frame_->height() == original_height); |
2003 } | 2003 } |
2004 | 2004 |
2005 | 2005 |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2462 // sp[2] : array or enum cache | 2462 // sp[2] : array or enum cache |
2463 // sp[3] : 0 or map | 2463 // sp[3] : 0 or map |
2464 // sp[4] : enumerable | 2464 // sp[4] : enumerable |
2465 // Grab the current frame's height for the break and continue | 2465 // Grab the current frame's height for the break and continue |
2466 // targets only after all the state is pushed on the frame. | 2466 // targets only after all the state is pushed on the frame. |
2467 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); | 2467 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); |
2468 node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY); | 2468 node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY); |
2469 | 2469 |
2470 __ ldr(r0, frame_->ElementAt(0)); // load the current count | 2470 __ ldr(r0, frame_->ElementAt(0)); // load the current count |
2471 __ ldr(r1, frame_->ElementAt(1)); // load the length | 2471 __ ldr(r1, frame_->ElementAt(1)); // load the length |
2472 __ cmp(r0, Operand(r1)); // compare to the array length | 2472 __ cmp(r0, r1); // compare to the array length |
2473 node->break_target()->Branch(hs); | 2473 node->break_target()->Branch(hs); |
2474 | 2474 |
2475 __ ldr(r0, frame_->ElementAt(0)); | 2475 __ ldr(r0, frame_->ElementAt(0)); |
2476 | 2476 |
2477 // Get the i'th entry of the array. | 2477 // Get the i'th entry of the array. |
2478 __ ldr(r2, frame_->ElementAt(2)); | 2478 __ ldr(r2, frame_->ElementAt(2)); |
2479 __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 2479 __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
2480 __ ldr(r3, MemOperand(r2, r0, LSL, kPointerSizeLog2 - kSmiTagSize)); | 2480 __ ldr(r3, MemOperand(r2, r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
2481 | 2481 |
2482 // Get Map or 0. | 2482 // Get Map or 0. |
(...skipping 2055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4538 | 4538 |
4539 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { | 4539 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { |
4540 VirtualFrame::SpilledScope spilled_scope(frame_); | 4540 VirtualFrame::SpilledScope spilled_scope(frame_); |
4541 ASSERT(args->length() == 2); | 4541 ASSERT(args->length() == 2); |
4542 | 4542 |
4543 // Load the two objects into registers and perform the comparison. | 4543 // Load the two objects into registers and perform the comparison. |
4544 LoadAndSpill(args->at(0)); | 4544 LoadAndSpill(args->at(0)); |
4545 LoadAndSpill(args->at(1)); | 4545 LoadAndSpill(args->at(1)); |
4546 frame_->EmitPop(r0); | 4546 frame_->EmitPop(r0); |
4547 frame_->EmitPop(r1); | 4547 frame_->EmitPop(r1); |
4548 __ cmp(r0, Operand(r1)); | 4548 __ cmp(r0, r1); |
4549 cc_reg_ = eq; | 4549 cc_reg_ = eq; |
4550 } | 4550 } |
4551 | 4551 |
4552 | 4552 |
4553 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { | 4553 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { |
4554 #ifdef DEBUG | 4554 #ifdef DEBUG |
4555 int original_height = frame_->height(); | 4555 int original_height = frame_->height(); |
4556 #endif | 4556 #endif |
4557 VirtualFrame::SpilledScope spilled_scope(frame_); | 4557 VirtualFrame::SpilledScope spilled_scope(frame_); |
4558 if (CheckForInlineRuntimeCall(node)) { | 4558 if (CheckForInlineRuntimeCall(node)) { |
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5766 // Handle the case where the lhs and rhs are the same object. | 5766 // Handle the case where the lhs and rhs are the same object. |
5767 // Equality is almost reflexive (everything but NaN), so this is a test | 5767 // Equality is almost reflexive (everything but NaN), so this is a test |
5768 // for "identity and not NaN". | 5768 // for "identity and not NaN". |
5769 static void EmitIdenticalObjectComparison(MacroAssembler* masm, | 5769 static void EmitIdenticalObjectComparison(MacroAssembler* masm, |
5770 Label* slow, | 5770 Label* slow, |
5771 Condition cc, | 5771 Condition cc, |
5772 bool never_nan_nan) { | 5772 bool never_nan_nan) { |
5773 Label not_identical; | 5773 Label not_identical; |
5774 Label heap_number, return_equal; | 5774 Label heap_number, return_equal; |
5775 Register exp_mask_reg = r5; | 5775 Register exp_mask_reg = r5; |
5776 __ cmp(r0, Operand(r1)); | 5776 __ cmp(r0, r1); |
5777 __ b(ne, ¬_identical); | 5777 __ b(ne, ¬_identical); |
5778 | 5778 |
5779 // The two objects are identical. If we know that one of them isn't NaN then | 5779 // The two objects are identical. If we know that one of them isn't NaN then |
5780 // we now know they test equal. | 5780 // we now know they test equal. |
5781 if (cc != eq || !never_nan_nan) { | 5781 if (cc != eq || !never_nan_nan) { |
5782 __ mov(exp_mask_reg, Operand(HeapNumber::kExponentMask)); | 5782 __ mov(exp_mask_reg, Operand(HeapNumber::kExponentMask)); |
5783 | 5783 |
5784 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), | 5784 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), |
5785 // so we do the second best thing - test it ourselves. | 5785 // so we do the second best thing - test it ourselves. |
5786 // They are both equal and they are not both Smis so both of them are not | 5786 // They are both equal and they are not both Smis so both of them are not |
5787 // Smis. If it's not a heap number, then return equal. | 5787 // Smis. If it's not a heap number, then return equal. |
5788 if (cc == lt || cc == gt) { | 5788 if (cc == lt || cc == gt) { |
5789 __ CompareObjectType(r0, r4, r4, FIRST_JS_OBJECT_TYPE); | 5789 __ CompareObjectType(r0, r4, r4, FIRST_JS_OBJECT_TYPE); |
5790 __ b(ge, slow); | 5790 __ b(ge, slow); |
5791 } else { | 5791 } else { |
5792 __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE); | 5792 __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE); |
5793 __ b(eq, &heap_number); | 5793 __ b(eq, &heap_number); |
5794 // Comparing JS objects with <=, >= is complicated. | 5794 // Comparing JS objects with <=, >= is complicated. |
5795 if (cc != eq) { | 5795 if (cc != eq) { |
5796 __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE)); | 5796 __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE)); |
5797 __ b(ge, slow); | 5797 __ b(ge, slow); |
5798 // Normally here we fall through to return_equal, but undefined is | 5798 // Normally here we fall through to return_equal, but undefined is |
5799 // special: (undefined == undefined) == true, but | 5799 // special: (undefined == undefined) == true, but |
5800 // (undefined <= undefined) == false! See ECMAScript 11.8.5. | 5800 // (undefined <= undefined) == false! See ECMAScript 11.8.5. |
5801 if (cc == le || cc == ge) { | 5801 if (cc == le || cc == ge) { |
5802 __ cmp(r4, Operand(ODDBALL_TYPE)); | 5802 __ cmp(r4, Operand(ODDBALL_TYPE)); |
5803 __ b(ne, &return_equal); | 5803 __ b(ne, &return_equal); |
5804 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 5804 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
5805 __ cmp(r0, Operand(r2)); | 5805 __ cmp(r0, r2); |
5806 __ b(ne, &return_equal); | 5806 __ b(ne, &return_equal); |
5807 if (cc == le) { | 5807 if (cc == le) { |
5808 // undefined <= undefined should fail. | 5808 // undefined <= undefined should fail. |
5809 __ mov(r0, Operand(GREATER)); | 5809 __ mov(r0, Operand(GREATER)); |
5810 } else { | 5810 } else { |
5811 // undefined >= undefined should fail. | 5811 // undefined >= undefined should fail. |
5812 __ mov(r0, Operand(LESS)); | 5812 __ mov(r0, Operand(LESS)); |
5813 } | 5813 } |
5814 __ mov(pc, Operand(lr)); // Return. | 5814 __ mov(pc, Operand(lr)); // Return. |
5815 } | 5815 } |
(...skipping 2315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8131 // Check that the fourth object is a JSArray object. | 8131 // Check that the fourth object is a JSArray object. |
8132 __ ldr(r0, MemOperand(sp, kLastMatchInfoOffset)); | 8132 __ ldr(r0, MemOperand(sp, kLastMatchInfoOffset)); |
8133 __ tst(r0, Operand(kSmiTagMask)); | 8133 __ tst(r0, Operand(kSmiTagMask)); |
8134 __ b(eq, &runtime); | 8134 __ b(eq, &runtime); |
8135 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE); | 8135 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE); |
8136 __ b(ne, &runtime); | 8136 __ b(ne, &runtime); |
8137 // Check that the JSArray is in fast case. | 8137 // Check that the JSArray is in fast case. |
8138 __ ldr(last_match_info_elements, | 8138 __ ldr(last_match_info_elements, |
8139 FieldMemOperand(r0, JSArray::kElementsOffset)); | 8139 FieldMemOperand(r0, JSArray::kElementsOffset)); |
8140 __ ldr(r0, FieldMemOperand(last_match_info_elements, HeapObject::kMapOffset)); | 8140 __ ldr(r0, FieldMemOperand(last_match_info_elements, HeapObject::kMapOffset)); |
8141 __ cmp(r0, Operand(Factory::fixed_array_map())); | 8141 __ LoadRoot(ip, kFixedArrayMapRootIndex); |
| 8142 __ cmp(r0, ip); |
8142 __ b(ne, &runtime); | 8143 __ b(ne, &runtime); |
8143 // Check that the last match info has space for the capture registers and the | 8144 // Check that the last match info has space for the capture registers and the |
8144 // additional information. | 8145 // additional information. |
8145 __ ldr(r0, | 8146 __ ldr(r0, |
8146 FieldMemOperand(last_match_info_elements, FixedArray::kLengthOffset)); | 8147 FieldMemOperand(last_match_info_elements, FixedArray::kLengthOffset)); |
8147 __ add(r2, r2, Operand(RegExpImpl::kLastMatchOverhead)); | 8148 __ add(r2, r2, Operand(RegExpImpl::kLastMatchOverhead)); |
8148 __ cmp(r2, r0); | 8149 __ cmp(r2, r0); |
8149 __ b(gt, &runtime); | 8150 __ b(gt, &runtime); |
8150 | 8151 |
8151 // subject: Subject string | 8152 // subject: Subject string |
(...skipping 1198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9350 | 9351 |
9351 // Just jump to runtime to add the two strings. | 9352 // Just jump to runtime to add the two strings. |
9352 __ bind(&string_add_runtime); | 9353 __ bind(&string_add_runtime); |
9353 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 9354 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
9354 } | 9355 } |
9355 | 9356 |
9356 | 9357 |
9357 #undef __ | 9358 #undef __ |
9358 | 9359 |
9359 } } // namespace v8::internal | 9360 } } // namespace v8::internal |
OLD | NEW |