| 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 5637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5648 __ orr(r4, lhs_mantissa, Operand(lhs_exponent, LSL, kSmiTagSize), SetCC); | 5648 __ orr(r4, lhs_mantissa, Operand(lhs_exponent, LSL, kSmiTagSize), SetCC); |
| 5649 __ mov(r0, Operand(r4), LeaveCC, ne); | 5649 __ mov(r0, Operand(r4), LeaveCC, ne); |
| 5650 __ mov(pc, Operand(lr), LeaveCC, ne); // Return conditionally. | 5650 __ mov(pc, Operand(lr), LeaveCC, ne); // Return conditionally. |
| 5651 // Now they are equal if and only if the lhs exponent is zero in its | 5651 // Now they are equal if and only if the lhs exponent is zero in its |
| 5652 // low 31 bits. | 5652 // low 31 bits. |
| 5653 __ mov(r0, Operand(rhs_exponent, LSL, kSmiTagSize)); | 5653 __ mov(r0, Operand(rhs_exponent, LSL, kSmiTagSize)); |
| 5654 __ mov(pc, Operand(lr)); | 5654 __ mov(pc, Operand(lr)); |
| 5655 } else { | 5655 } else { |
| 5656 // Call a native function to do a comparison between two non-NaNs. | 5656 // Call a native function to do a comparison between two non-NaNs. |
| 5657 // Call C routine that may not cause GC or other trouble. | 5657 // Call C routine that may not cause GC or other trouble. |
| 5658 __ mov(r5, Operand(ExternalReference::compare_doubles())); | 5658 __ push(lr); |
| 5659 __ Jump(r5); // Tail call. | 5659 __ PrepareCallCFunction(4, r5); // Two doubles count as 4 arguments. |
| 5660 __ CallCFunction(ExternalReference::compare_doubles(), 4); |
| 5661 __ pop(pc); // Return. |
| 5660 } | 5662 } |
| 5661 } | 5663 } |
| 5662 | 5664 |
| 5663 | 5665 |
| 5664 // See comment at call site. | 5666 // See comment at call site. |
| 5665 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm) { | 5667 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm) { |
| 5666 // If either operand is a JSObject or an oddball value, then they are | 5668 // If either operand is a JSObject or an oddball value, then they are |
| 5667 // not equal since their pointers are different. | 5669 // not equal since their pointers are different. |
| 5668 // There is no test for undetectability in strict equality. | 5670 // There is no test for undetectability in strict equality. |
| 5669 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); | 5671 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); |
| (...skipping 1406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7076 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | 7078 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); |
| 7077 __ pop(pc); | 7079 __ pop(pc); |
| 7078 } | 7080 } |
| 7079 | 7081 |
| 7080 | 7082 |
| 7081 void CEntryStub::GenerateCore(MacroAssembler* masm, | 7083 void CEntryStub::GenerateCore(MacroAssembler* masm, |
| 7082 Label* throw_normal_exception, | 7084 Label* throw_normal_exception, |
| 7083 Label* throw_termination_exception, | 7085 Label* throw_termination_exception, |
| 7084 Label* throw_out_of_memory_exception, | 7086 Label* throw_out_of_memory_exception, |
| 7085 bool do_gc, | 7087 bool do_gc, |
| 7086 bool always_allocate) { | 7088 bool always_allocate, |
| 7089 int frame_alignment_skew) { |
| 7087 // r0: result parameter for PerformGC, if any | 7090 // r0: result parameter for PerformGC, if any |
| 7088 // r4: number of arguments including receiver (C callee-saved) | 7091 // r4: number of arguments including receiver (C callee-saved) |
| 7089 // r5: pointer to builtin function (C callee-saved) | 7092 // r5: pointer to builtin function (C callee-saved) |
| 7090 // r6: pointer to the first argument (C callee-saved) | 7093 // r6: pointer to the first argument (C callee-saved) |
| 7091 | 7094 |
| 7092 if (do_gc) { | 7095 if (do_gc) { |
| 7093 // Passing r0. | 7096 // Passing r0. |
| 7094 ExternalReference gc_reference = ExternalReference::perform_gc_function(); | 7097 __ PrepareCallCFunction(1, r1); |
| 7095 __ Call(gc_reference.address(), RelocInfo::RUNTIME_ENTRY); | 7098 __ CallCFunction(ExternalReference::perform_gc_function(), 1); |
| 7096 } | 7099 } |
| 7097 | 7100 |
| 7098 ExternalReference scope_depth = | 7101 ExternalReference scope_depth = |
| 7099 ExternalReference::heap_always_allocate_scope_depth(); | 7102 ExternalReference::heap_always_allocate_scope_depth(); |
| 7100 if (always_allocate) { | 7103 if (always_allocate) { |
| 7101 __ mov(r0, Operand(scope_depth)); | 7104 __ mov(r0, Operand(scope_depth)); |
| 7102 __ ldr(r1, MemOperand(r0)); | 7105 __ ldr(r1, MemOperand(r0)); |
| 7103 __ add(r1, r1, Operand(1)); | 7106 __ add(r1, r1, Operand(1)); |
| 7104 __ str(r1, MemOperand(r0)); | 7107 __ str(r1, MemOperand(r0)); |
| 7105 } | 7108 } |
| 7106 | 7109 |
| 7107 // Call C built-in. | 7110 // Call C built-in. |
| 7108 // r0 = argc, r1 = argv | 7111 // r0 = argc, r1 = argv |
| 7109 __ mov(r0, Operand(r4)); | 7112 __ mov(r0, Operand(r4)); |
| 7110 __ mov(r1, Operand(r6)); | 7113 __ mov(r1, Operand(r6)); |
| 7111 | 7114 |
| 7115 int frame_alignment = MacroAssembler::ActivationFrameAlignment(); |
| 7116 int frame_alignment_mask = frame_alignment - 1; |
| 7117 #if defined(V8_HOST_ARCH_ARM) |
| 7118 if (FLAG_debug_code) { |
| 7119 if (frame_alignment > kPointerSize) { |
| 7120 Label alignment_as_expected; |
| 7121 ASSERT(IsPowerOf2(frame_alignment)); |
| 7122 __ sub(r2, sp, Operand(frame_alignment_skew)); |
| 7123 __ tst(r2, Operand(frame_alignment_mask)); |
| 7124 __ b(eq, &alignment_as_expected); |
| 7125 // Don't use Check here, as it will call Runtime_Abort re-entering here. |
| 7126 __ stop("Unexpected alignment"); |
| 7127 __ bind(&alignment_as_expected); |
| 7128 } |
| 7129 } |
| 7130 #endif |
| 7131 |
| 7132 // Just before the call (jump) below lr is pushed, so the actual alignment is |
| 7133 // adding one to the current skew. |
| 7134 int alignment_before_call = |
| 7135 (frame_alignment_skew + kPointerSize) & frame_alignment_mask; |
| 7136 if (alignment_before_call > 0) { |
| 7137 // Push until the alignment before the call is met. |
| 7138 __ mov(r2, Operand(0)); |
| 7139 for (int i = alignment_before_call; |
| 7140 (i & frame_alignment_mask) != 0; |
| 7141 i += kPointerSize) { |
| 7142 __ push(r2); |
| 7143 } |
| 7144 } |
| 7145 |
| 7112 // TODO(1242173): To let the GC traverse the return address of the exit | 7146 // TODO(1242173): To let the GC traverse the return address of the exit |
| 7113 // frames, we need to know where the return address is. Right now, | 7147 // frames, we need to know where the return address is. Right now, |
| 7114 // we push it on the stack to be able to find it again, but we never | 7148 // we push it on the stack to be able to find it again, but we never |
| 7115 // restore from it in case of changes, which makes it impossible to | 7149 // restore from it in case of changes, which makes it impossible to |
| 7116 // support moving the C entry code stub. This should be fixed, but currently | 7150 // support moving the C entry code stub. This should be fixed, but currently |
| 7117 // this is OK because the CEntryStub gets generated so early in the V8 boot | 7151 // this is OK because the CEntryStub gets generated so early in the V8 boot |
| 7118 // sequence that it is not moving ever. | 7152 // sequence that it is not moving ever. |
| 7119 masm->add(lr, pc, Operand(4)); // compute return address: (pc + 8) + 4 | 7153 masm->add(lr, pc, Operand(4)); // Compute return address: (pc + 8) + 4 |
| 7120 masm->push(lr); | 7154 masm->push(lr); |
| 7121 masm->Jump(r5); | 7155 masm->Jump(r5); |
| 7122 | 7156 |
| 7157 // Restore sp back to before aligning the stack. |
| 7158 if (alignment_before_call > 0) { |
| 7159 __ add(sp, sp, Operand(alignment_before_call)); |
| 7160 } |
| 7161 |
| 7123 if (always_allocate) { | 7162 if (always_allocate) { |
| 7124 // It's okay to clobber r2 and r3 here. Don't mess with r0 and r1 | 7163 // It's okay to clobber r2 and r3 here. Don't mess with r0 and r1 |
| 7125 // though (contain the result). | 7164 // though (contain the result). |
| 7126 __ mov(r2, Operand(scope_depth)); | 7165 __ mov(r2, Operand(scope_depth)); |
| 7127 __ ldr(r3, MemOperand(r2)); | 7166 __ ldr(r3, MemOperand(r2)); |
| 7128 __ sub(r3, r3, Operand(1)); | 7167 __ sub(r3, r3, Operand(1)); |
| 7129 __ str(r3, MemOperand(r2)); | 7168 __ str(r3, MemOperand(r2)); |
| 7130 } | 7169 } |
| 7131 | 7170 |
| 7132 // check for failure result | 7171 // check for failure result |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7199 Label throw_normal_exception; | 7238 Label throw_normal_exception; |
| 7200 Label throw_termination_exception; | 7239 Label throw_termination_exception; |
| 7201 Label throw_out_of_memory_exception; | 7240 Label throw_out_of_memory_exception; |
| 7202 | 7241 |
| 7203 // Call into the runtime system. | 7242 // Call into the runtime system. |
| 7204 GenerateCore(masm, | 7243 GenerateCore(masm, |
| 7205 &throw_normal_exception, | 7244 &throw_normal_exception, |
| 7206 &throw_termination_exception, | 7245 &throw_termination_exception, |
| 7207 &throw_out_of_memory_exception, | 7246 &throw_out_of_memory_exception, |
| 7208 false, | 7247 false, |
| 7209 false); | 7248 false, |
| 7249 -kPointerSize); |
| 7210 | 7250 |
| 7211 // Do space-specific GC and retry runtime call. | 7251 // Do space-specific GC and retry runtime call. |
| 7212 GenerateCore(masm, | 7252 GenerateCore(masm, |
| 7213 &throw_normal_exception, | 7253 &throw_normal_exception, |
| 7214 &throw_termination_exception, | 7254 &throw_termination_exception, |
| 7215 &throw_out_of_memory_exception, | 7255 &throw_out_of_memory_exception, |
| 7216 true, | 7256 true, |
| 7217 false); | 7257 false, |
| 7258 0); |
| 7218 | 7259 |
| 7219 // Do full GC and retry runtime call one final time. | 7260 // Do full GC and retry runtime call one final time. |
| 7220 Failure* failure = Failure::InternalError(); | 7261 Failure* failure = Failure::InternalError(); |
| 7221 __ mov(r0, Operand(reinterpret_cast<int32_t>(failure))); | 7262 __ mov(r0, Operand(reinterpret_cast<int32_t>(failure))); |
| 7222 GenerateCore(masm, | 7263 GenerateCore(masm, |
| 7223 &throw_normal_exception, | 7264 &throw_normal_exception, |
| 7224 &throw_termination_exception, | 7265 &throw_termination_exception, |
| 7225 &throw_out_of_memory_exception, | 7266 &throw_out_of_memory_exception, |
| 7226 true, | 7267 true, |
| 7227 true); | 7268 true, |
| 7269 kPointerSize); |
| 7228 | 7270 |
| 7229 __ bind(&throw_out_of_memory_exception); | 7271 __ bind(&throw_out_of_memory_exception); |
| 7230 GenerateThrowUncatchable(masm, OUT_OF_MEMORY); | 7272 GenerateThrowUncatchable(masm, OUT_OF_MEMORY); |
| 7231 | 7273 |
| 7232 __ bind(&throw_termination_exception); | 7274 __ bind(&throw_termination_exception); |
| 7233 GenerateThrowUncatchable(masm, TERMINATION); | 7275 GenerateThrowUncatchable(masm, TERMINATION); |
| 7234 | 7276 |
| 7235 __ bind(&throw_normal_exception); | 7277 __ bind(&throw_normal_exception); |
| 7236 GenerateThrowTOS(masm); | 7278 GenerateThrowTOS(masm); |
| 7237 } | 7279 } |
| (...skipping 1659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8897 | 8939 |
| 8898 // Just jump to runtime to add the two strings. | 8940 // Just jump to runtime to add the two strings. |
| 8899 __ bind(&string_add_runtime); | 8941 __ bind(&string_add_runtime); |
| 8900 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 8942 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
| 8901 } | 8943 } |
| 8902 | 8944 |
| 8903 | 8945 |
| 8904 #undef __ | 8946 #undef __ |
| 8905 | 8947 |
| 8906 } } // namespace v8::internal | 8948 } } // namespace v8::internal |
| OLD | NEW |