| 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 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 // Return and remove the on-stack parameters. | 235 // Return and remove the on-stack parameters. |
| 236 __ ret(3 * kPointerSize); | 236 __ ret(3 * kPointerSize); |
| 237 | 237 |
| 238 __ bind(&slow_case); | 238 __ bind(&slow_case); |
| 239 __ TailCallRuntime(Runtime::kCreateArrayLiteralShallow, 3, 1); | 239 __ TailCallRuntime(Runtime::kCreateArrayLiteralShallow, 3, 1); |
| 240 } | 240 } |
| 241 | 241 |
| 242 | 242 |
| 243 // NOTE: The stub does not handle the inlined cases (Smis, Booleans, undefined). | 243 // NOTE: The stub does not handle the inlined cases (Smis, Booleans, undefined). |
| 244 void ToBooleanStub::Generate(MacroAssembler* masm) { | 244 void ToBooleanStub::Generate(MacroAssembler* masm) { |
| 245 // This stub overrides SometimesSetsUpAFrame() to return false. That means | |
| 246 // we cannot call anything that could cause a GC from this stub. | |
| 247 Label false_result, true_result, not_string; | 245 Label false_result, true_result, not_string; |
| 248 __ mov(eax, Operand(esp, 1 * kPointerSize)); | 246 __ mov(eax, Operand(esp, 1 * kPointerSize)); |
| 249 Factory* factory = masm->isolate()->factory(); | 247 Factory* factory = masm->isolate()->factory(); |
| 250 | 248 |
| 251 // undefined -> false | 249 // undefined -> false |
| 252 __ cmp(eax, factory->undefined_value()); | 250 __ cmp(eax, factory->undefined_value()); |
| 253 __ j(equal, &false_result); | 251 __ j(equal, &false_result); |
| 254 | 252 |
| 255 // Boolean -> its value | 253 // Boolean -> its value |
| 256 __ cmp(eax, factory->true_value()); | 254 __ cmp(eax, factory->true_value()); |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 Immediate(HeapNumber::kSignMask)); // Flip sign. | 714 Immediate(HeapNumber::kSignMask)); // Flip sign. |
| 717 } else { | 715 } else { |
| 718 __ mov(edx, Operand(eax)); | 716 __ mov(edx, Operand(eax)); |
| 719 // edx: operand | 717 // edx: operand |
| 720 | 718 |
| 721 Label slow_allocate_heapnumber, heapnumber_allocated; | 719 Label slow_allocate_heapnumber, heapnumber_allocated; |
| 722 __ AllocateHeapNumber(eax, ebx, ecx, &slow_allocate_heapnumber); | 720 __ AllocateHeapNumber(eax, ebx, ecx, &slow_allocate_heapnumber); |
| 723 __ jmp(&heapnumber_allocated); | 721 __ jmp(&heapnumber_allocated); |
| 724 | 722 |
| 725 __ bind(&slow_allocate_heapnumber); | 723 __ bind(&slow_allocate_heapnumber); |
| 726 { | 724 __ EnterInternalFrame(); |
| 727 FrameScope scope(masm, StackFrame::INTERNAL); | 725 __ push(edx); |
| 728 __ push(edx); | 726 __ CallRuntime(Runtime::kNumberAlloc, 0); |
| 729 __ CallRuntime(Runtime::kNumberAlloc, 0); | 727 __ pop(edx); |
| 730 __ pop(edx); | 728 __ LeaveInternalFrame(); |
| 731 } | |
| 732 | 729 |
| 733 __ bind(&heapnumber_allocated); | 730 __ bind(&heapnumber_allocated); |
| 734 // eax: allocated 'empty' number | 731 // eax: allocated 'empty' number |
| 735 __ mov(ecx, FieldOperand(edx, HeapNumber::kExponentOffset)); | 732 __ mov(ecx, FieldOperand(edx, HeapNumber::kExponentOffset)); |
| 736 __ xor_(ecx, HeapNumber::kSignMask); // Flip sign. | 733 __ xor_(ecx, HeapNumber::kSignMask); // Flip sign. |
| 737 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ecx); | 734 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ecx); |
| 738 __ mov(ecx, FieldOperand(edx, HeapNumber::kMantissaOffset)); | 735 __ mov(ecx, FieldOperand(edx, HeapNumber::kMantissaOffset)); |
| 739 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx); | 736 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx); |
| 740 } | 737 } |
| 741 __ ret(0); | 738 __ ret(0); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 764 | 761 |
| 765 // Try to store the result in a heap number. | 762 // Try to store the result in a heap number. |
| 766 __ bind(&try_float); | 763 __ bind(&try_float); |
| 767 if (mode_ == UNARY_NO_OVERWRITE) { | 764 if (mode_ == UNARY_NO_OVERWRITE) { |
| 768 Label slow_allocate_heapnumber, heapnumber_allocated; | 765 Label slow_allocate_heapnumber, heapnumber_allocated; |
| 769 __ mov(ebx, eax); | 766 __ mov(ebx, eax); |
| 770 __ AllocateHeapNumber(eax, edx, edi, &slow_allocate_heapnumber); | 767 __ AllocateHeapNumber(eax, edx, edi, &slow_allocate_heapnumber); |
| 771 __ jmp(&heapnumber_allocated); | 768 __ jmp(&heapnumber_allocated); |
| 772 | 769 |
| 773 __ bind(&slow_allocate_heapnumber); | 770 __ bind(&slow_allocate_heapnumber); |
| 774 { | 771 __ EnterInternalFrame(); |
| 775 FrameScope scope(masm, StackFrame::INTERNAL); | 772 // Push the original HeapNumber on the stack. The integer value can't |
| 776 // Push the original HeapNumber on the stack. The integer value can't | 773 // be stored since it's untagged and not in the smi range (so we can't |
| 777 // be stored since it's untagged and not in the smi range (so we can't | 774 // smi-tag it). We'll recalculate the value after the GC instead. |
| 778 // smi-tag it). We'll recalculate the value after the GC instead. | 775 __ push(ebx); |
| 779 __ push(ebx); | 776 __ CallRuntime(Runtime::kNumberAlloc, 0); |
| 780 __ CallRuntime(Runtime::kNumberAlloc, 0); | 777 // New HeapNumber is in eax. |
| 781 // New HeapNumber is in eax. | 778 __ pop(edx); |
| 782 __ pop(edx); | 779 __ LeaveInternalFrame(); |
| 783 } | |
| 784 // IntegerConvert uses ebx and edi as scratch registers. | 780 // IntegerConvert uses ebx and edi as scratch registers. |
| 785 // This conversion won't go slow-case. | 781 // This conversion won't go slow-case. |
| 786 IntegerConvert(masm, edx, CpuFeatures::IsSupported(SSE3), slow); | 782 IntegerConvert(masm, edx, CpuFeatures::IsSupported(SSE3), slow); |
| 787 __ not_(ecx); | 783 __ not_(ecx); |
| 788 | 784 |
| 789 __ bind(&heapnumber_allocated); | 785 __ bind(&heapnumber_allocated); |
| 790 } | 786 } |
| 791 if (CpuFeatures::IsSupported(SSE2)) { | 787 if (CpuFeatures::IsSupported(SSE2)) { |
| 792 CpuFeatures::Scope use_sse2(SSE2); | 788 CpuFeatures::Scope use_sse2(SSE2); |
| 793 __ cvtsi2sd(xmm0, Operand(ecx)); | 789 __ cvtsi2sd(xmm0, Operand(ecx)); |
| (...skipping 1491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2285 __ bind(&skip_cache); | 2281 __ bind(&skip_cache); |
| 2286 __ sub(Operand(esp), Immediate(kDoubleSize)); | 2282 __ sub(Operand(esp), Immediate(kDoubleSize)); |
| 2287 __ movdbl(Operand(esp, 0), xmm1); | 2283 __ movdbl(Operand(esp, 0), xmm1); |
| 2288 __ fld_d(Operand(esp, 0)); | 2284 __ fld_d(Operand(esp, 0)); |
| 2289 GenerateOperation(masm); | 2285 GenerateOperation(masm); |
| 2290 __ fstp_d(Operand(esp, 0)); | 2286 __ fstp_d(Operand(esp, 0)); |
| 2291 __ movdbl(xmm1, Operand(esp, 0)); | 2287 __ movdbl(xmm1, Operand(esp, 0)); |
| 2292 __ add(Operand(esp), Immediate(kDoubleSize)); | 2288 __ add(Operand(esp), Immediate(kDoubleSize)); |
| 2293 // We return the value in xmm1 without adding it to the cache, but | 2289 // We return the value in xmm1 without adding it to the cache, but |
| 2294 // we cause a scavenging GC so that future allocations will succeed. | 2290 // we cause a scavenging GC so that future allocations will succeed. |
| 2295 { | 2291 __ EnterInternalFrame(); |
| 2296 FrameScope scope(masm, StackFrame::INTERNAL); | 2292 // Allocate an unused object bigger than a HeapNumber. |
| 2297 // Allocate an unused object bigger than a HeapNumber. | 2293 __ push(Immediate(Smi::FromInt(2 * kDoubleSize))); |
| 2298 __ push(Immediate(Smi::FromInt(2 * kDoubleSize))); | 2294 __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace); |
| 2299 __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace); | 2295 __ LeaveInternalFrame(); |
| 2300 } | |
| 2301 __ Ret(); | 2296 __ Ret(); |
| 2302 } | 2297 } |
| 2303 | 2298 |
| 2304 // Call runtime, doing whatever allocation and cleanup is necessary. | 2299 // Call runtime, doing whatever allocation and cleanup is necessary. |
| 2305 if (tagged) { | 2300 if (tagged) { |
| 2306 __ bind(&runtime_call_clear_stack); | 2301 __ bind(&runtime_call_clear_stack); |
| 2307 __ fstp(0); | 2302 __ fstp(0); |
| 2308 __ bind(&runtime_call); | 2303 __ bind(&runtime_call); |
| 2309 ExternalReference runtime = | 2304 ExternalReference runtime = |
| 2310 ExternalReference(RuntimeFunction(), masm->isolate()); | 2305 ExternalReference(RuntimeFunction(), masm->isolate()); |
| 2311 __ TailCallExternalReference(runtime, 1, 1); | 2306 __ TailCallExternalReference(runtime, 1, 1); |
| 2312 } else { // UNTAGGED. | 2307 } else { // UNTAGGED. |
| 2313 __ bind(&runtime_call_clear_stack); | 2308 __ bind(&runtime_call_clear_stack); |
| 2314 __ bind(&runtime_call); | 2309 __ bind(&runtime_call); |
| 2315 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); | 2310 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); |
| 2316 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm1); | 2311 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm1); |
| 2317 { | 2312 __ EnterInternalFrame(); |
| 2318 FrameScope scope(masm, StackFrame::INTERNAL); | 2313 __ push(eax); |
| 2319 __ push(eax); | 2314 __ CallRuntime(RuntimeFunction(), 1); |
| 2320 __ CallRuntime(RuntimeFunction(), 1); | 2315 __ LeaveInternalFrame(); |
| 2321 } | |
| 2322 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); | 2316 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); |
| 2323 __ Ret(); | 2317 __ Ret(); |
| 2324 } | 2318 } |
| 2325 } | 2319 } |
| 2326 | 2320 |
| 2327 | 2321 |
| 2328 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { | 2322 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { |
| 2329 switch (type_) { | 2323 switch (type_) { |
| 2330 case TranscendentalCache::SIN: return Runtime::kMath_sin; | 2324 case TranscendentalCache::SIN: return Runtime::kMath_sin; |
| 2331 case TranscendentalCache::COS: return Runtime::kMath_cos; | 2325 case TranscendentalCache::COS: return Runtime::kMath_cos; |
| (...skipping 2192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4524 if (HasArgsInRegisters()) { | 4518 if (HasArgsInRegisters()) { |
| 4525 // Push arguments below return address. | 4519 // Push arguments below return address. |
| 4526 __ pop(scratch); | 4520 __ pop(scratch); |
| 4527 __ push(object); | 4521 __ push(object); |
| 4528 __ push(function); | 4522 __ push(function); |
| 4529 __ push(scratch); | 4523 __ push(scratch); |
| 4530 } | 4524 } |
| 4531 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 4525 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
| 4532 } else { | 4526 } else { |
| 4533 // Call the builtin and convert 0/1 to true/false. | 4527 // Call the builtin and convert 0/1 to true/false. |
| 4534 { | 4528 __ EnterInternalFrame(); |
| 4535 FrameScope scope(masm, StackFrame::INTERNAL); | 4529 __ push(object); |
| 4536 __ push(object); | 4530 __ push(function); |
| 4537 __ push(function); | 4531 __ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_FUNCTION); |
| 4538 __ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_FUNCTION); | 4532 __ LeaveInternalFrame(); |
| 4539 } | |
| 4540 Label true_value, done; | 4533 Label true_value, done; |
| 4541 __ test(eax, Operand(eax)); | 4534 __ test(eax, Operand(eax)); |
| 4542 __ j(zero, &true_value, Label::kNear); | 4535 __ j(zero, &true_value, Label::kNear); |
| 4543 __ mov(eax, factory->false_value()); | 4536 __ mov(eax, factory->false_value()); |
| 4544 __ jmp(&done, Label::kNear); | 4537 __ jmp(&done, Label::kNear); |
| 4545 __ bind(&true_value); | 4538 __ bind(&true_value); |
| 4546 __ mov(eax, factory->true_value()); | 4539 __ mov(eax, factory->true_value()); |
| 4547 __ bind(&done); | 4540 __ bind(&done); |
| 4548 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); | 4541 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); |
| 4549 } | 4542 } |
| (...skipping 1409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5959 } | 5952 } |
| 5960 | 5953 |
| 5961 | 5954 |
| 5962 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { | 5955 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { |
| 5963 // Save the registers. | 5956 // Save the registers. |
| 5964 __ pop(ecx); | 5957 __ pop(ecx); |
| 5965 __ push(edx); | 5958 __ push(edx); |
| 5966 __ push(eax); | 5959 __ push(eax); |
| 5967 __ push(ecx); | 5960 __ push(ecx); |
| 5968 | 5961 |
| 5969 { | 5962 // Call the runtime system in a fresh internal frame. |
| 5970 // Call the runtime system in a fresh internal frame. | 5963 ExternalReference miss = ExternalReference(IC_Utility(IC::kCompareIC_Miss), |
| 5971 ExternalReference miss = ExternalReference(IC_Utility(IC::kCompareIC_Miss), | 5964 masm->isolate()); |
| 5972 masm->isolate()); | 5965 __ EnterInternalFrame(); |
| 5973 FrameScope scope(masm, StackFrame::INTERNAL); | 5966 __ push(edx); |
| 5974 __ push(edx); | 5967 __ push(eax); |
| 5975 __ push(eax); | 5968 __ push(Immediate(Smi::FromInt(op_))); |
| 5976 __ push(Immediate(Smi::FromInt(op_))); | 5969 __ CallExternalReference(miss, 3); |
| 5977 __ CallExternalReference(miss, 3); | 5970 __ LeaveInternalFrame(); |
| 5978 } | |
| 5979 | 5971 |
| 5980 // Compute the entry point of the rewritten stub. | 5972 // Compute the entry point of the rewritten stub. |
| 5981 __ lea(edi, FieldOperand(eax, Code::kHeaderSize)); | 5973 __ lea(edi, FieldOperand(eax, Code::kHeaderSize)); |
| 5982 | 5974 |
| 5983 // Restore registers. | 5975 // Restore registers. |
| 5984 __ pop(ecx); | 5976 __ pop(ecx); |
| 5985 __ pop(eax); | 5977 __ pop(eax); |
| 5986 __ pop(edx); | 5978 __ pop(edx); |
| 5987 __ push(ecx); | 5979 __ push(ecx); |
| 5988 | 5980 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6109 __ push(r0); | 6101 __ push(r0); |
| 6110 __ CallStub(&stub); | 6102 __ CallStub(&stub); |
| 6111 | 6103 |
| 6112 __ test(r1, Operand(r1)); | 6104 __ test(r1, Operand(r1)); |
| 6113 __ j(zero, miss); | 6105 __ j(zero, miss); |
| 6114 __ jmp(done); | 6106 __ jmp(done); |
| 6115 } | 6107 } |
| 6116 | 6108 |
| 6117 | 6109 |
| 6118 void StringDictionaryLookupStub::Generate(MacroAssembler* masm) { | 6110 void StringDictionaryLookupStub::Generate(MacroAssembler* masm) { |
| 6119 // This stub overrides SometimesSetsUpAFrame() to return false. That means | |
| 6120 // we cannot call anything that could cause a GC from this stub. | |
| 6121 // Stack frame on entry: | 6111 // Stack frame on entry: |
| 6122 // esp[0 * kPointerSize]: return address. | 6112 // esp[0 * kPointerSize]: return address. |
| 6123 // esp[1 * kPointerSize]: key's hash. | 6113 // esp[1 * kPointerSize]: key's hash. |
| 6124 // esp[2 * kPointerSize]: key. | 6114 // esp[2 * kPointerSize]: key. |
| 6125 // Registers: | 6115 // Registers: |
| 6126 // dictionary_: StringDictionary to probe. | 6116 // dictionary_: StringDictionary to probe. |
| 6127 // result_: used as scratch. | 6117 // result_: used as scratch. |
| 6128 // index_: will hold an index of entry if lookup is successful. | 6118 // index_: will hold an index of entry if lookup is successful. |
| 6129 // might alias with result_. | 6119 // might alias with result_. |
| 6130 // Returns: | 6120 // Returns: |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6203 __ Drop(1); | 6193 __ Drop(1); |
| 6204 __ ret(2 * kPointerSize); | 6194 __ ret(2 * kPointerSize); |
| 6205 } | 6195 } |
| 6206 | 6196 |
| 6207 | 6197 |
| 6208 #undef __ | 6198 #undef __ |
| 6209 | 6199 |
| 6210 } } // namespace v8::internal | 6200 } } // namespace v8::internal |
| 6211 | 6201 |
| 6212 #endif // V8_TARGET_ARCH_IA32 | 6202 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |