Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 5720005: Add an untagged double to transcendental cache elements. They now contain an... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 2524 matching lines...) Expand 10 before | Expand all | Expand 10 after
2535 __ test(eax, Operand(eax)); 2535 __ test(eax, Operand(eax));
2536 __ j(zero, &runtime_call_clear_stack); 2536 __ j(zero, &runtime_call_clear_stack);
2537 #ifdef DEBUG 2537 #ifdef DEBUG
2538 // Check that the layout of cache elements match expectations. 2538 // Check that the layout of cache elements match expectations.
2539 { TranscendentalCache::Element test_elem[2]; 2539 { TranscendentalCache::Element test_elem[2];
2540 char* elem_start = reinterpret_cast<char*>(&test_elem[0]); 2540 char* elem_start = reinterpret_cast<char*>(&test_elem[0]);
2541 char* elem2_start = reinterpret_cast<char*>(&test_elem[1]); 2541 char* elem2_start = reinterpret_cast<char*>(&test_elem[1]);
2542 char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0])); 2542 char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0]));
2543 char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1])); 2543 char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1]));
2544 char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output)); 2544 char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output));
2545 CHECK_EQ(12, elem2_start - elem_start); // Two uint_32's and a pointer. 2545 char* elem_uout = reinterpret_cast<char*>(&(test_elem[0].untagged_output));
2546 CHECK_EQ(20, elem2_start - elem_start); // Two uint_32's and a pointer.
2546 CHECK_EQ(0, elem_in0 - elem_start); 2547 CHECK_EQ(0, elem_in0 - elem_start);
2547 CHECK_EQ(kIntSize, elem_in1 - elem_start); 2548 CHECK_EQ(kIntSize, elem_in1 - elem_start);
2548 CHECK_EQ(2 * kIntSize, elem_out - elem_start); 2549 CHECK_EQ(2 * kIntSize, elem_out - elem_start);
2550 CHECK_EQ(3 * kIntSize, elem_uout - elem_start);
2549 } 2551 }
2550 #endif 2552 #endif
2551 // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*12]. 2553 // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*20].
2552 __ lea(ecx, Operand(ecx, ecx, times_2, 0)); 2554 __ lea(ecx, Operand(ecx, ecx, times_4, 0));
2553 __ lea(ecx, Operand(eax, ecx, times_4, 0)); 2555 __ lea(ecx, Operand(eax, ecx, times_4, 0));
2554 // Check if cache matches: Double value is stored in uint32_t[2] array. 2556 // Check if cache matches: Double value is stored in uint32_t[2] array.
2555 NearLabel cache_miss; 2557 NearLabel cache_miss, allocate_cached_answer;
2556 __ cmp(ebx, Operand(ecx, 0)); 2558 __ cmp(ebx, Operand(ecx, 0));
2557 __ j(not_equal, &cache_miss); 2559 __ j(not_equal, &cache_miss);
2558 __ cmp(edx, Operand(ecx, kIntSize)); 2560 __ cmp(edx, Operand(ecx, kIntSize));
2559 __ j(not_equal, &cache_miss); 2561 __ j(not_equal, &cache_miss);
2560 // Cache hit! 2562 // Cache hit!
2561 __ mov(eax, Operand(ecx, 2 * kIntSize)); 2563 __ mov(eax, Operand(ecx, 2 * kIntSize));
2562 __ fstp(0); 2564 __ fstp(0);
2565 __ test(eax, Operand(eax));
2566 __ j(zero, &allocate_cached_answer); // The answer is cached as untagged.
Erik Corry 2010/12/13 20:26:13 "is cached, but only as untagged".
2567 __ ret(kPointerSize);
2568
2569 __ bind(&allocate_cached_answer);
2570 __ AllocateHeapNumber(eax, edi, edx, &runtime_call);
2571 __ mov(ebx, Operand(ecx, 3 * kIntSize));
2572 __ mov(FieldOperand(eax, HeapNumber::kValueOffset), ebx);
2573 __ mov(ebx, Operand(ecx, 4 * kIntSize));
2574 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx);
2575 __ mov(Operand(ecx, 2 * kIntSize), eax);
2563 __ ret(kPointerSize); 2576 __ ret(kPointerSize);
2564 2577
2565 __ bind(&cache_miss); 2578 __ bind(&cache_miss);
2566 // Update cache with new value. 2579 // Update cache with new value.
2567 // We are short on registers, so use no_reg as scratch. 2580 // We are short on registers, so use no_reg as scratch.
2568 // This gives slightly larger code. 2581 // This gives slightly larger code.
2569 __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack); 2582 __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack);
2570 GenerateOperation(masm); 2583 GenerateOperation(masm);
2571 __ mov(Operand(ecx, 0), ebx); 2584 __ mov(Operand(ecx, 0), ebx);
2572 __ mov(Operand(ecx, kIntSize), edx); 2585 __ mov(Operand(ecx, kIntSize), edx);
2573 __ mov(Operand(ecx, 2 * kIntSize), eax); 2586 __ mov(Operand(ecx, 2 * kIntSize), eax);
2587 __ fst_d(Operand(ecx, 3 * kIntSize));
2574 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); 2588 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
2575 __ ret(kPointerSize); 2589 __ ret(kPointerSize);
2576 2590
2577 __ bind(&runtime_call_clear_stack); 2591 __ bind(&runtime_call_clear_stack);
2578 __ fstp(0); 2592 __ fstp(0);
2579 __ bind(&runtime_call); 2593 __ bind(&runtime_call);
2580 __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1); 2594 __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1);
2581 } 2595 }
2582 2596
2583 2597
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2728 __ test(eax, Operand(eax)); 2742 __ test(eax, Operand(eax));
2729 __ j(zero, &call_runtime); 2743 __ j(zero, &call_runtime);
2730 #ifdef DEBUG 2744 #ifdef DEBUG
2731 // Check that the layout of cache elements match expectations. 2745 // Check that the layout of cache elements match expectations.
2732 { TranscendentalCache::Element test_elem[2]; 2746 { TranscendentalCache::Element test_elem[2];
2733 char* elem_start = reinterpret_cast<char*>(&test_elem[0]); 2747 char* elem_start = reinterpret_cast<char*>(&test_elem[0]);
2734 char* elem2_start = reinterpret_cast<char*>(&test_elem[1]); 2748 char* elem2_start = reinterpret_cast<char*>(&test_elem[1]);
2735 char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0])); 2749 char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0]));
2736 char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1])); 2750 char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1]));
2737 char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output)); 2751 char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output));
2738 CHECK_EQ(12, elem2_start - elem_start); // Two uint_32's and a pointer. 2752 char* elem_uout = reinterpret_cast<char*>(&(test_elem[0].untagged_output));
2753 CHECK_EQ(20, elem2_start - elem_start); // Two uint_32's and a pointer.
Erik Corry 2010/12/13 20:26:13 Comment is now wrong and type has wrong name.
2739 CHECK_EQ(0, elem_in0 - elem_start); 2754 CHECK_EQ(0, elem_in0 - elem_start);
2740 CHECK_EQ(kIntSize, elem_in1 - elem_start); 2755 CHECK_EQ(kIntSize, elem_in1 - elem_start);
2741 CHECK_EQ(2 * kIntSize, elem_out - elem_start); 2756 CHECK_EQ(2 * kIntSize, elem_out - elem_start);
2757 CHECK_EQ(3 * kIntSize, elem_uout - elem_start);
2742 } 2758 }
2743 #endif 2759 #endif
2744 // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*12]. 2760 // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*12].
2745 __ lea(ecx, Operand(ecx, ecx, times_2, 0)); 2761 __ lea(ecx, Operand(ecx, ecx, times_4, 0));
2746 __ lea(ecx, Operand(eax, ecx, times_4, 0)); 2762 __ lea(ecx, Operand(eax, ecx, times_4, 0));
2747 // Check if cache matches: Double value is stored in uint32_t[2] array. 2763 // Check if cache matches: Double value is stored in uint32_t[2] array.
2748 NearLabel cache_miss; 2764 NearLabel cache_miss;
2749 __ cmp(ebx, Operand(ecx, 0)); 2765 __ cmp(ebx, Operand(ecx, 0));
2750 __ j(not_equal, &cache_miss); 2766 __ j(not_equal, &cache_miss);
2751 __ cmp(edx, Operand(ecx, kIntSize)); 2767 __ cmp(edx, Operand(ecx, kIntSize));
2752 __ j(not_equal, &cache_miss); 2768 __ j(not_equal, &cache_miss);
2753 // Cache hit! 2769 // Cache hit!
2754 __ mov(eax, Operand(ecx, 2 * kIntSize)); 2770 __ movdbl(xmm1, Operand(ecx, 3 * kIntSize));
2755 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
2756 __ Ret(); 2771 __ Ret();
2757 2772
2758 __ bind(&cache_miss); 2773 __ bind(&cache_miss);
2759 // Update cache with new value. 2774 // Update cache with new value.
2760 // We are short on registers, so use no_reg as scratch. 2775 // We are short on registers, so use no_reg as scratch.
2761 // This gives slightly larger code. 2776 // This gives slightly larger code.
2762 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); 2777 __ sub(Operand(esp), Immediate(kDoubleSize));
2763 __ sub(Operand(esp), Immediate(sizeof(double)));
2764 __ movdbl(Operand(esp, 0), xmm1); 2778 __ movdbl(Operand(esp, 0), xmm1);
2765 __ fld_d(Operand(esp, 0)); 2779 __ fld_d(Operand(esp, 0));
2766 __ add(Operand(esp), Immediate(sizeof(double))); 2780 __ add(Operand(esp), Immediate(kDoubleSize));
2767 GenerateOperation(masm); 2781 GenerateOperation(masm);
2768 __ mov(Operand(ecx, 0), ebx); 2782 __ mov(Operand(ecx, 0), ebx);
2769 __ mov(Operand(ecx, kIntSize), edx); 2783 __ mov(Operand(ecx, kIntSize), edx);
2770 __ mov(Operand(ecx, 2 * kIntSize), eax); 2784 __ mov(Operand(ecx, 2 * kIntSize), Immediate(0)); // No tagged cached value.
2771 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); 2785 __ fst_d(Operand(ecx, 3 * kIntSize));
2772 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 2786 __ movdbl(xmm1, Operand(ecx, 3 * kIntSize));
2773 __ Ret(); 2787 __ Ret();
2774 2788
2775 __ bind(&skip_cache); 2789 __ bind(&skip_cache);
2776 __ sub(Operand(esp), Immediate(2 * kPointerSize)); 2790 __ sub(Operand(esp), Immediate(kDoubleSize));
2777 __ movdbl(Operand(esp, 0), xmm1); 2791 __ movdbl(Operand(esp, 0), xmm1);
2778 __ fld_d(Operand(esp, 0)); 2792 __ fld_d(Operand(esp, 0));
2779 GenerateOperation(masm); 2793 GenerateOperation(masm);
2780 __ fstp_d(Operand(esp, 0)); 2794 __ fstp_d(Operand(esp, 0));
2781 __ movdbl(xmm1, Operand(esp, 0)); 2795 __ movdbl(xmm1, Operand(esp, 0));
2782 __ add(Operand(esp), Immediate(2 * kPointerSize)); 2796 __ add(Operand(esp), Immediate(kDoubleSize));
2783 __ Ret(); 2797 __ Ret();
2784 2798
2785 __ bind(&call_runtime); 2799 __ bind(&call_runtime);
2786 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); 2800 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache);
2787 __ push(eax); 2801 __ push(eax);
2788 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm1); 2802 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm1);
2789 __ CallRuntime(RuntimeFunction(), 1); 2803 __ CallRuntime(RuntimeFunction(), 1);
2790 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 2804 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
2791 __ Ret(); 2805 __ Ret();
2792 } 2806 }
(...skipping 3621 matching lines...) Expand 10 before | Expand all | Expand 10 after
6414 // Do a tail call to the rewritten stub. 6428 // Do a tail call to the rewritten stub.
6415 __ jmp(Operand(edi)); 6429 __ jmp(Operand(edi));
6416 } 6430 }
6417 6431
6418 6432
6419 #undef __ 6433 #undef __
6420 6434
6421 } } // namespace v8::internal 6435 } } // namespace v8::internal
6422 6436
6423 #endif // V8_TARGET_ARCH_IA32 6437 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698