| 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 |