OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 | 739 |
740 // Tag the result as a smi and we're done. | 740 // Tag the result as a smi and we're done. |
741 STATIC_ASSERT(kSmiTagSize == 1); | 741 STATIC_ASSERT(kSmiTagSize == 1); |
742 __ lea(eax, Operand(ecx, times_2, kSmiTag)); | 742 __ lea(eax, Operand(ecx, times_2, kSmiTag)); |
743 __ ret(0); | 743 __ ret(0); |
744 | 744 |
745 // Try to store the result in a heap number. | 745 // Try to store the result in a heap number. |
746 __ bind(&try_float); | 746 __ bind(&try_float); |
747 if (mode_ == UNARY_NO_OVERWRITE) { | 747 if (mode_ == UNARY_NO_OVERWRITE) { |
748 Label slow_allocate_heapnumber, heapnumber_allocated; | 748 Label slow_allocate_heapnumber, heapnumber_allocated; |
| 749 __ mov(ebx, eax); |
749 __ AllocateHeapNumber(eax, edx, edi, &slow_allocate_heapnumber); | 750 __ AllocateHeapNumber(eax, edx, edi, &slow_allocate_heapnumber); |
750 __ jmp(&heapnumber_allocated); | 751 __ jmp(&heapnumber_allocated); |
751 | 752 |
752 __ bind(&slow_allocate_heapnumber); | 753 __ bind(&slow_allocate_heapnumber); |
753 __ EnterInternalFrame(); | 754 __ EnterInternalFrame(); |
754 __ push(ecx); | 755 // Push the original HeapNumber on the stack. The integer value can't |
| 756 // be stored since it's untagged and not in the smi range (so we can't |
| 757 // smi-tag it). We'll recalculate the value after the GC instead. |
| 758 __ push(ebx); |
755 __ CallRuntime(Runtime::kNumberAlloc, 0); | 759 __ CallRuntime(Runtime::kNumberAlloc, 0); |
756 __ pop(ecx); | 760 // New HeapNumber is in eax. |
| 761 __ pop(edx); |
757 __ LeaveInternalFrame(); | 762 __ LeaveInternalFrame(); |
| 763 // IntegerConvert uses ebx and edi as scratch registers. |
| 764 // This conversion won't go slow-case. |
| 765 IntegerConvert(masm, edx, CpuFeatures::IsSupported(SSE3), slow); |
| 766 __ not_(ecx); |
758 | 767 |
759 __ bind(&heapnumber_allocated); | 768 __ bind(&heapnumber_allocated); |
760 } | 769 } |
761 if (CpuFeatures::IsSupported(SSE2)) { | 770 if (CpuFeatures::IsSupported(SSE2)) { |
762 CpuFeatures::Scope use_sse2(SSE2); | 771 CpuFeatures::Scope use_sse2(SSE2); |
763 __ cvtsi2sd(xmm0, Operand(ecx)); | 772 __ cvtsi2sd(xmm0, Operand(ecx)); |
764 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); | 773 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); |
765 } else { | 774 } else { |
766 __ push(ecx); | 775 __ push(ecx); |
767 __ fild_s(Operand(esp, 0)); | 776 __ fild_s(Operand(esp, 0)); |
(...skipping 3422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4190 ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, masm->isolate()); | 4199 ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, masm->isolate()); |
4191 __ push(Operand::StaticVariable(c_entry_fp)); | 4200 __ push(Operand::StaticVariable(c_entry_fp)); |
4192 | 4201 |
4193 #ifdef ENABLE_LOGGING_AND_PROFILING | 4202 #ifdef ENABLE_LOGGING_AND_PROFILING |
4194 // If this is the outermost JS call, set js_entry_sp value. | 4203 // If this is the outermost JS call, set js_entry_sp value. |
4195 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, | 4204 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, |
4196 masm->isolate()); | 4205 masm->isolate()); |
4197 __ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0)); | 4206 __ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0)); |
4198 __ j(not_equal, ¬_outermost_js); | 4207 __ j(not_equal, ¬_outermost_js); |
4199 __ mov(Operand::StaticVariable(js_entry_sp), ebp); | 4208 __ mov(Operand::StaticVariable(js_entry_sp), ebp); |
| 4209 __ push(Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); |
| 4210 Label cont; |
| 4211 __ jmp(&cont); |
4200 __ bind(¬_outermost_js); | 4212 __ bind(¬_outermost_js); |
| 4213 __ push(Immediate(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME))); |
| 4214 __ bind(&cont); |
4201 #endif | 4215 #endif |
4202 | 4216 |
4203 // Call a faked try-block that does the invoke. | 4217 // Call a faked try-block that does the invoke. |
4204 __ call(&invoke); | 4218 __ call(&invoke); |
4205 | 4219 |
4206 // Caught exception: Store result (exception) in the pending | 4220 // Caught exception: Store result (exception) in the pending |
4207 // exception field in the JSEnv and return a failure sentinel. | 4221 // exception field in the JSEnv and return a failure sentinel. |
4208 ExternalReference pending_exception(Isolate::k_pending_exception_address, | 4222 ExternalReference pending_exception(Isolate::k_pending_exception_address, |
4209 masm->isolate()); | 4223 masm->isolate()); |
4210 __ mov(Operand::StaticVariable(pending_exception), eax); | 4224 __ mov(Operand::StaticVariable(pending_exception), eax); |
(...skipping 25 matching lines...) Expand all Loading... |
4236 } else { | 4250 } else { |
4237 ExternalReference entry(Builtins::kJSEntryTrampoline, | 4251 ExternalReference entry(Builtins::kJSEntryTrampoline, |
4238 masm->isolate()); | 4252 masm->isolate()); |
4239 __ mov(edx, Immediate(entry)); | 4253 __ mov(edx, Immediate(entry)); |
4240 } | 4254 } |
4241 __ mov(edx, Operand(edx, 0)); // deref address | 4255 __ mov(edx, Operand(edx, 0)); // deref address |
4242 __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); | 4256 __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); |
4243 __ call(Operand(edx)); | 4257 __ call(Operand(edx)); |
4244 | 4258 |
4245 // Unlink this frame from the handler chain. | 4259 // Unlink this frame from the handler chain. |
4246 __ pop(Operand::StaticVariable(ExternalReference( | 4260 __ PopTryHandler(); |
4247 Isolate::k_handler_address, | |
4248 masm->isolate()))); | |
4249 // Pop next_sp. | |
4250 __ add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); | |
4251 | 4261 |
| 4262 __ bind(&exit); |
4252 #ifdef ENABLE_LOGGING_AND_PROFILING | 4263 #ifdef ENABLE_LOGGING_AND_PROFILING |
4253 // If current EBP value is the same as js_entry_sp value, it means that | 4264 // Check if the current stack frame is marked as the outermost JS frame. |
4254 // the current function is the outermost. | 4265 __ pop(ebx); |
4255 __ cmp(ebp, Operand::StaticVariable(js_entry_sp)); | 4266 __ cmp(Operand(ebx), |
| 4267 Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); |
4256 __ j(not_equal, ¬_outermost_js_2); | 4268 __ j(not_equal, ¬_outermost_js_2); |
4257 __ mov(Operand::StaticVariable(js_entry_sp), Immediate(0)); | 4269 __ mov(Operand::StaticVariable(js_entry_sp), Immediate(0)); |
4258 __ bind(¬_outermost_js_2); | 4270 __ bind(¬_outermost_js_2); |
4259 #endif | 4271 #endif |
4260 | 4272 |
4261 // Restore the top frame descriptor from the stack. | 4273 // Restore the top frame descriptor from the stack. |
4262 __ bind(&exit); | |
4263 __ pop(Operand::StaticVariable(ExternalReference( | 4274 __ pop(Operand::StaticVariable(ExternalReference( |
4264 Isolate::k_c_entry_fp_address, | 4275 Isolate::k_c_entry_fp_address, |
4265 masm->isolate()))); | 4276 masm->isolate()))); |
4266 | 4277 |
4267 // Restore callee-saved registers (C calling conventions). | 4278 // Restore callee-saved registers (C calling conventions). |
4268 __ pop(ebx); | 4279 __ pop(ebx); |
4269 __ pop(esi); | 4280 __ pop(esi); |
4270 __ pop(edi); | 4281 __ pop(edi); |
4271 __ add(Operand(esp), Immediate(2 * kPointerSize)); // remove markers | 4282 __ add(Operand(esp), Immediate(2 * kPointerSize)); // remove markers |
4272 | 4283 |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4663 void StringCharCodeAtGenerator::GenerateSlow( | 4674 void StringCharCodeAtGenerator::GenerateSlow( |
4664 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { | 4675 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { |
4665 __ Abort("Unexpected fallthrough to CharCodeAt slow case"); | 4676 __ Abort("Unexpected fallthrough to CharCodeAt slow case"); |
4666 | 4677 |
4667 // Index is not a smi. | 4678 // Index is not a smi. |
4668 __ bind(&index_not_smi_); | 4679 __ bind(&index_not_smi_); |
4669 // If index is a heap number, try converting it to an integer. | 4680 // If index is a heap number, try converting it to an integer. |
4670 __ CheckMap(index_, | 4681 __ CheckMap(index_, |
4671 masm->isolate()->factory()->heap_number_map(), | 4682 masm->isolate()->factory()->heap_number_map(), |
4672 index_not_number_, | 4683 index_not_number_, |
4673 true); | 4684 DONT_DO_SMI_CHECK); |
4674 call_helper.BeforeCall(masm); | 4685 call_helper.BeforeCall(masm); |
4675 __ push(object_); | 4686 __ push(object_); |
4676 __ push(index_); | 4687 __ push(index_); |
4677 __ push(index_); // Consumed by runtime conversion function. | 4688 __ push(index_); // Consumed by runtime conversion function. |
4678 if (index_flags_ == STRING_INDEX_IS_NUMBER) { | 4689 if (index_flags_ == STRING_INDEX_IS_NUMBER) { |
4679 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); | 4690 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); |
4680 } else { | 4691 } else { |
4681 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); | 4692 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); |
4682 // NumberToSmi discards numbers that are not exact integers. | 4693 // NumberToSmi discards numbers that are not exact integers. |
4683 __ CallRuntime(Runtime::kNumberToSmi, 1); | 4694 __ CallRuntime(Runtime::kNumberToSmi, 1); |
(...skipping 1466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6150 __ Drop(1); | 6161 __ Drop(1); |
6151 __ ret(2 * kPointerSize); | 6162 __ ret(2 * kPointerSize); |
6152 } | 6163 } |
6153 | 6164 |
6154 | 6165 |
6155 #undef __ | 6166 #undef __ |
6156 | 6167 |
6157 } } // namespace v8::internal | 6168 } } // namespace v8::internal |
6158 | 6169 |
6159 #endif // V8_TARGET_ARCH_IA32 | 6170 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |