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

Unified Diff: src/arm/code-stubs-arm.cc

Issue 6591073: ARM: Implement untagged input for TranscendentalCacheStub. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 10 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/arm/codegen-arm.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/code-stubs-arm.cc
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 7d374eecd79829f84b147fcd3f4f833bc4745ece..5d5c6c793e094583b7e5f770fc0f3a0a8add57ec 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -3072,32 +3072,43 @@ void TypeRecordingBinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
- // Argument is a number and is on stack and in r0.
- Label runtime_call;
Label input_not_smi;
Label loaded;
+ Label runtime_call;
+ Label invalid_cache;
+ const Register scratch0 = r9;
+ const Register scratch1 = r10;
Søren Thygesen Gjesse 2011/03/02 10:09:45 As discussed offline using r10 here is might be th
Karl Klose 2011/03/02 11:16:41 Yes, it is. Used different register.
+ const Register tagged_input = r7;
+ const bool tagged = (argument_type_ == TAGGED);
if (CpuFeatures::IsSupported(VFP3)) {
- // Load argument and check if it is a smi.
- __ JumpIfNotSmi(r0, &input_not_smi);
-
CpuFeatures::Scope scope(VFP3);
- // Input is a smi. Convert to double and load the low and high words
- // of the double into r2, r3.
- __ IntegerToDoubleConversionWithVFP3(r0, r3, r2);
- __ b(&loaded);
-
- __ bind(&input_not_smi);
- // Check if input is a HeapNumber.
- __ CheckMap(r0,
- r1,
- Heap::kHeapNumberMapRootIndex,
- &runtime_call,
- true);
- // Input is a HeapNumber. Load it to a double register and store the
- // low and high words into r2, r3.
- __ Ldrd(r2, r3, FieldMemOperand(r0, HeapNumber::kValueOffset));
+ if (tagged) {
+ // Argument is a number and is on stack and in r0.
+ // Load argument and check if it is a smi.
+ __ JumpIfNotSmi(r0, &input_not_smi);
+ CpuFeatures::Scope scope(VFP3);
Søren Thygesen Gjesse 2011/03/02 10:09:45 Duplicate CpuFeatures::Scope.
Karl Klose 2011/03/02 11:16:41 Done, removed.
+ // Input is a smi. Convert to double and load the low and high words
+ // of the double into r2, r3.
+ __ IntegerToDoubleConversionWithVFP3(r0, r3, r2);
+ __ b(&loaded);
+
+ __ bind(&input_not_smi);
+ // Check if input is a HeapNumber.
+ __ CheckMap(r0,
+ r1,
+ Heap::kHeapNumberMapRootIndex,
+ &runtime_call,
+ true);
+ // Input is a HeapNumber. Load it to a double register and store the
+ // low and high words into r2, r3.
+ __ vldr(d0, FieldMemOperand(r0, HeapNumber::kValueOffset));
+ __ vmov(r2, r3, d0);
+ } else {
+ // Input is untagged double in d2. Output goes to d2.
+ __ vmov(r2, r3, d2);
+ }
__ bind(&loaded);
// r2 = low 32 bits of double value
// r3 = high 32 bits of double value
@@ -3119,7 +3130,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
// r0 points to the cache for the type type_.
// If NULL, the cache hasn't been initialized yet, so go through runtime.
__ cmp(r0, Operand(0, RelocInfo::NONE));
- __ b(eq, &runtime_call);
+ __ b(eq, &invalid_cache);
#ifdef DEBUG
// Check that the layout of cache elements match expectations.
@@ -3140,19 +3151,117 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
__ add(r1, r1, Operand(r1, LSL, 1));
__ add(r0, r0, Operand(r1, LSL, 2));
// Check if cache matches: Double value is stored in uint32_t[2] array.
- __ ldm(ia, r0, r4.bit()| r5.bit() | r6.bit());
+ __ ldm(ia, r0, r4.bit() | r5.bit() | r6.bit());
__ cmp(r2, r4);
__ b(ne, &runtime_call);
__ cmp(r3, r5);
__ b(ne, &runtime_call);
- // Cache hit. Load result, pop argument and return.
- __ mov(r0, Operand(r6));
- __ pop();
+ // Cache hit. Load result, cleanup and return.
+ if (tagged) {
+ // Pop input value from stack and load result into r0.
+ __ pop();
+ __ mov(r0, Operand(r6));
+ } else {
+ //__ stop("cache hit");
Søren Thygesen Gjesse 2011/03/02 10:09:45 Debug code.
Karl Klose 2011/03/02 11:16:41 Done.
+ // Load result into d2.
+ __ vldr(d2, FieldMemOperand(r6, HeapNumber::kValueOffset));
+ }
__ Ret();
- }
+ } // if (CpuFeatures::IsSupported(VFP3))
Søren Thygesen Gjesse 2011/03/02 10:09:45 Two spaces before //.
Karl Klose 2011/03/02 11:16:41 Done.
__ bind(&runtime_call);
Søren Thygesen Gjesse 2011/03/02 10:09:45 Maybe the name of this label should be "calculate"
Karl Klose 2011/03/02 11:16:41 Done.
- __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1);
+ if (tagged) {
+ __ bind(&invalid_cache);
+ __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1);
+ } else {
+ if (!CpuFeatures::IsSupported(VFP3)) UNREACHABLE();
+ CpuFeatures::Scope scope(VFP3);
+
+ Register cache_entry = r0;
+ Register heap_number_map = r5;
+ Label no_update;
+ Label skip_cache;
+
+ // Call C function to calculate the result and update the cache.
+ __ push(r0);
Søren Thygesen Gjesse 2011/03/02 10:09:45 r0 -> cache_entry
Karl Klose 2011/03/02 11:16:41 Done.
+ __ push(lr);
Søren Thygesen Gjesse 2011/03/02 10:09:45 The code for calling the C functions are repeated.
Karl Klose 2011/03/02 11:16:41 Done.
+ __ PrepareCallCFunction(2, scratch0);
+ __ vmov(r0, r1, d2);
+ switch(type_) {
+ case TranscendentalCache::SIN:
+ __ CallCFunction(ExternalReference::math_sin_double_function(), 2);
+ break;
+ case TranscendentalCache::COS:
+ __ CallCFunction(ExternalReference::math_cos_double_function(), 2);
+ break;
+ case TranscendentalCache::LOG:
+ __ CallCFunction(ExternalReference::math_log_double_function(), 2);
+ break;
+ default:
+ UNIMPLEMENTED();
+ break;
+ }
+ __ pop(lr);
+ __ GetCFunctionDoubleResult(d2);
+
+ // Try to update the cache.
+ __ pop(cache_entry);
+
+ // Check if the cache is valid.
+ __ cmp(r0, Operand(0, RelocInfo::NONE));
+ __ b(&no_update, eq);
+ __ LoadRoot(r5, Heap::kHeapNumberMapRootIndex);
+ __ AllocateHeapNumber(r6, scratch0, scratch1, r5, &no_update);
+ __ vstr(d2, FieldMemOperand(r6, HeapNumber::kValueOffset));
+ __ stm(ia, cache_entry, r2.bit() | r3.bit() | r6.bit());
+ __ bind(&no_update);
+ __ Ret();
+
+ __ bind(&skip_cache);
+ // Call C function to calculate the result and answer directly
+ // without updating the cache.
+ __ push(lr);
+ __ PrepareCallCFunction(2, scratch0);
+ __ vmov(r0, r1, d2);
+ switch(type_) {
+ case TranscendentalCache::SIN:
+ __ CallCFunction(ExternalReference::math_sin_double_function(), 2);
+ break;
+ case TranscendentalCache::COS:
+ __ CallCFunction(ExternalReference::math_cos_double_function(), 2);
+ break;
+ case TranscendentalCache::LOG:
+ __ CallCFunction(ExternalReference::math_log_double_function(), 2);
+ break;
+ default:
+ UNIMPLEMENTED();
+ break;
+ }
+ __ pop(lr);
+ __ GetCFunctionDoubleResult(d2);
+ // We return the value in d2 without adding it to the cache, but
+ // we cause a scavenging GC so that future allocations will succeed.
+ __ EnterInternalFrame();
+ // Allocate an unused object bigger than a HeapNumber.
+ __ mov(scratch0, Operand(Smi::FromInt(2 * kDoubleSize)));
Søren Thygesen Gjesse 2011/03/02 10:09:45 Shouldn't HeapNumber::kSize be enough? Allocating
Karl Klose 2011/03/02 11:16:41 Done.
+ __ push(scratch0);
+ __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace);
+ __ LeaveInternalFrame();
+ __ Ret();
+
+ __ bind(&invalid_cache);
+ // The cache is invalid. Call runtime which will recreate the
+ // cache.
+ __ LoadRoot(r5, Heap::kHeapNumberMapRootIndex);
+ __ AllocateHeapNumber(r6, scratch0, scratch1, r5, &skip_cache);
Søren Thygesen Gjesse 2011/03/02 10:09:45 Any reason for having the skip cache code before t
Karl Klose 2011/03/02 11:16:41 There is no reason. I changed the order.
+ __ vstr(d2, FieldMemOperand(r6, HeapNumber::kValueOffset));
+ __ EnterInternalFrame();
+ __ push(r6);
+ __ CallRuntime(RuntimeFunction(), 1);
+ __ LeaveInternalFrame();
+ __ vldr(d2, FieldMemOperand(r0, HeapNumber::kValueOffset));
+ __ Ret();
+ }
}
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/arm/codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698