Index: src/code-stub-assembler.cc |
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
index d3b4d99352cd8df190e906b3c9b23f9ba7916109..9d38079b645da2182713cd9a4dce95b2d9fc5dd9 100644 |
--- a/src/code-stub-assembler.cc |
+++ b/src/code-stub-assembler.cc |
@@ -2831,6 +2831,85 @@ Node* CodeStubAssembler::StringToNumber(Node* context, Node* input) { |
return var_result.value(); |
} |
+Node* CodeStubAssembler::NumberToString(compiler::Node* context, |
+ compiler::Node* argument) { |
+ Variable result(this, MachineRepresentation::kTagged); |
+ Label runtime(this, Label::kDeferred); |
+ Label smi(this); |
+ Label done(this, &result); |
+ |
+ // Load the number string cache. |
+ Node* number_string_cache = LoadRoot(Heap::kNumberStringCacheRootIndex); |
+ |
+ // Make the hash mask from the length of the number string cache. It |
+ // contains two elements (number and string) for each cache entry. |
+ Node* mask = LoadFixedArrayBaseLength(number_string_cache); |
+ Node* one = IntPtrConstant(1); |
+ mask = IntPtrSub(mask, one); |
+ |
+ GotoIf(WordIsSmi(argument), &smi); |
+ |
+ // Argument isn't smi, check to see if it's a heap-number. |
+ Node* map = LoadMap(argument); |
+ GotoUnless(WordEqual(map, HeapNumberMapConstant()), &runtime); |
+ |
+ // Make a hash from the two 32-bit values of the double. |
+ Node* low = |
+ LoadObjectField(argument, HeapNumber::kValueOffset, MachineType::Int32()); |
+ Node* high = LoadObjectField(argument, HeapNumber::kValueOffset + kIntSize, |
+ MachineType::Int32()); |
+ Node* hash = Word32Xor(low, high); |
+ if (Is64()) hash = ChangeInt32ToInt64(hash); |
+ hash = WordShl(hash, one); |
+ Node* index = WordAnd(hash, SmiToWord(mask)); |
+ |
+ // Cache entry's key must be a heap number |
+ Node* number_key = |
+ LoadFixedArrayElement(number_string_cache, index, 0, INTPTR_PARAMETERS); |
+ GotoIf(WordIsSmi(number_key), &runtime); |
+ map = LoadMap(number_key); |
+ GotoUnless(WordEqual(map, HeapNumberMapConstant()), &runtime); |
+ |
+ // Cache entry's key must match the heap number value we're looking for. |
+ Node* low_compare = LoadObjectField(number_key, HeapNumber::kValueOffset, |
+ MachineType::Int32()); |
+ Node* high_compare = LoadObjectField( |
+ number_key, HeapNumber::kValueOffset + kIntSize, MachineType::Int32()); |
+ GotoUnless(WordEqual(low, low_compare), &runtime); |
+ GotoUnless(WordEqual(high, high_compare), &runtime); |
+ |
+ // Heap number match, return value fro cache entry. |
+ IncrementCounter(isolate()->counters()->number_to_string_native(), 1); |
+ result.Bind(LoadFixedArrayElement(number_string_cache, index, kPointerSize, |
+ INTPTR_PARAMETERS)); |
+ Goto(&done); |
+ |
+ Bind(&runtime); |
+ { |
+ // No cache entry, go to the runtime. |
+ result.Bind(CallRuntime(Runtime::kNumberToString, context, argument)); |
+ } |
+ Goto(&done); |
+ |
+ Bind(&smi); |
+ { |
+ // Load the smi key, make sure it matches the smi we're looking for. |
+ Node* smi_index = WordAnd(WordShl(argument, one), mask); |
+ Node* smi_key = LoadFixedArrayElement(number_string_cache, smi_index, 0, |
+ SMI_PARAMETERS); |
+ GotoIf(WordNotEqual(smi_key, argument), &runtime); |
+ |
+ // Smi match, return value from cache entry. |
+ IncrementCounter(isolate()->counters()->number_to_string_native(), 1); |
+ result.Bind(LoadFixedArrayElement(number_string_cache, smi_index, |
+ kPointerSize, SMI_PARAMETERS)); |
+ Goto(&done); |
+ } |
+ |
+ Bind(&done); |
+ return result.value(); |
+} |
+ |
Node* CodeStubAssembler::ToName(Node* context, Node* value) { |
typedef CodeStubAssembler::Label Label; |
typedef CodeStubAssembler::Variable Variable; |