Revision: 16874
Author: [email protected]
Date: Mon Sep 23 10:58:45 2013 UTC
Log: Turn the NumberToStringStub into a hydrogen stub.
This adds a BuildLookupNumberStringCache() in Hydrogen, which will
be used by the hydrogen version of StringAddStub, in addition to the
hydrogen version of NumberToStringStub.
[email protected]
Review URL: https://codereview.chromium.org/23726041
http://code.google.com/p/v8/source/detail?r=16874
Modified:
/branches/bleeding_edge/src/arm/code-stubs-arm.cc
/branches/bleeding_edge/src/arm/code-stubs-arm.h
/branches/bleeding_edge/src/arm/full-codegen-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/code-stubs-hydrogen.cc
/branches/bleeding_edge/src/code-stubs.h
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/hydrogen.h
/branches/bleeding_edge/src/ia32/code-stubs-ia32.cc
/branches/bleeding_edge/src/ia32/code-stubs-ia32.h
/branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/x64/code-stubs-x64.cc
/branches/bleeding_edge/src/x64/code-stubs-x64.h
/branches/bleeding_edge/src/x64/full-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Fri Sep 20 09:27:40
2013 UTC
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Mon Sep 23 10:58:45
2013 UTC
@@ -57,6 +57,16 @@
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
}
+
+
+void NumberToStringStub::InitializeInterfaceDescriptor(
+ Isolate* isolate,
+ CodeStubInterfaceDescriptor* descriptor) {
+ static Register registers[] = { r0 };
+ descriptor->register_param_count_ = 1;
+ descriptor->register_params_ = registers;
+ descriptor->deoptimization_handler_ = NULL;
+}
void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
@@ -970,22 +980,6 @@
__ eor(r0, r0, Operand(1 << Map::kIsUndetectable));
__ Ret();
}
-
-
-void NumberToStringStub::Generate(MacroAssembler* masm) {
- Label runtime;
-
- __ ldr(r1, MemOperand(sp, 0));
-
- // Generate code to lookup number in the number string cache.
- __ LookupNumberStringCache(r1, r0, r2, r3, r4, &runtime);
- __ add(sp, sp, Operand(1 * kPointerSize));
- __ Ret();
-
- __ bind(&runtime);
- // Handle number to string in the runtime system if not found in the
cache.
- __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1);
-}
static void ICCompareStub_CheckInputType(MacroAssembler* masm,
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.h Thu Sep 19 06:07:23
2013 UTC
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.h Mon Sep 23 10:58:45
2013 UTC
@@ -252,18 +252,6 @@
| HeapNumberRegisterBits::encode(the_heap_number_.code())
| ScratchRegisterBits::encode(scratch_.code());
}
-
- void Generate(MacroAssembler* masm);
-};
-
-
-class NumberToStringStub: public PlatformCodeStub {
- public:
- NumberToStringStub() { }
-
- private:
- Major MajorKey() { return NumberToString; }
- int MinorKey() { return 0; }
void Generate(MacroAssembler* masm);
};
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Thu Sep 19 09:08:08
2013 UTC
+++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Mon Sep 23 10:58:45
2013 UTC
@@ -3590,8 +3590,8 @@
void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
ASSERT_EQ(args->length(), 1);
- // Load the argument on the stack and call the stub.
- VisitForStackValue(args->at(0));
+ // Load the argument into r0 and call the stub.
+ VisitForAccumulatorValue(args->at(0));
NumberToStringStub stub;
__ CallStub(&stub);
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri Sep 20
12:32:31 2013 UTC
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon Sep 23
10:58:45 2013 UTC
@@ -1090,11 +1090,6 @@
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
break;
}
- case CodeStub::NumberToString: {
- NumberToStringStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
- break;
- }
case CodeStub::StringCompare: {
StringCompareStub stub;
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
=======================================
--- /branches/bleeding_edge/src/code-stubs-hydrogen.cc Fri Sep 20 09:27:40
2013 UTC
+++ /branches/bleeding_edge/src/code-stubs-hydrogen.cc Mon Sep 23 10:58:45
2013 UTC
@@ -336,6 +336,19 @@
Handle<Code> ToNumberStub::GenerateCode(Isolate* isolate) {
return DoGenerateCode(isolate, this);
}
+
+
+template <>
+HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() {
+ info()->MarkAsSavesCallerDoubles();
+ HValue* number = GetParameter(NumberToStringStub::kNumber);
+ return BuildNumberToString(number);
+}
+
+
+Handle<Code> NumberToStringStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
+}
template <>
=======================================
--- /branches/bleeding_edge/src/code-stubs.h Fri Sep 13 09:57:48 2013 UTC
+++ /branches/bleeding_edge/src/code-stubs.h Mon Sep 23 10:58:45 2013 UTC
@@ -464,6 +464,25 @@
};
+class NumberToStringStub V8_FINAL : public HydrogenCodeStub {
+ public:
+ NumberToStringStub() {}
+
+ virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE;
+
+ virtual void InitializeInterfaceDescriptor(
+ Isolate* isolate,
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
+
+ // Parameters accessed via CodeStubGraphBuilder::GetParameter()
+ static const int kNumber = 0;
+
+ private:
+ virtual Major MajorKey() V8_OVERRIDE { return NumberToString; }
+ virtual int NotMissMinorKey() V8_OVERRIDE { return 0; }
+};
+
+
class FastNewClosureStub : public HydrogenCodeStub {
public:
explicit FastNewClosureStub(LanguageMode language_mode, bool
is_generator)
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Fri Sep 20 12:32:31
2013 UTC
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Mon Sep 23 10:58:45
2013 UTC
@@ -5666,6 +5666,18 @@
return HObjectAccess(
kDouble, HeapNumber::kValueOffset, Representation::Double());
}
+
+ static HObjectAccess ForHeapNumberValueLowestBits() {
+ return HObjectAccess(kDouble,
+ HeapNumber::kValueOffset,
+ Representation::Integer32());
+ }
+
+ static HObjectAccess ForHeapNumberValueHighestBits() {
+ return HObjectAccess(kDouble,
+ HeapNumber::kValueOffset + kIntSize,
+ Representation::Integer32());
+ }
static HObjectAccess ForElementsPointer() {
return HObjectAccess(kElementsPointer, JSObject::kElementsOffset);
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Fri Sep 20 11:34:05 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc Mon Sep 23 10:58:45 2013 UTC
@@ -1271,6 +1271,142 @@
Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map);
}
+
+
+HValue* HGraphBuilder::BuildLookupNumberStringCache(
+ HValue* object,
+ HIfContinuation* continuation) {
+ // Create a joinable continuation.
+ HIfContinuation found(graph()->CreateBasicBlock(),
+ graph()->CreateBasicBlock());
+
+ // Load the number string cache.
+ HValue* number_string_cache =
+ Add<HLoadRoot>(Heap::kNumberStringCacheRootIndex);
+
+ // Make the hash maks from the length of the number string cache. It
+ // contains two elements (number and string) for each cache entry.
+ HValue* mask = AddLoadFixedArrayLength(number_string_cache);
+ mask->set_type(HType::Smi());
+ mask = Add<HSar>(mask, graph()->GetConstant1());
+ mask = Add<HSub>(mask, graph()->GetConstant1());
+
+ // Check whether object is a smi.
+ IfBuilder if_objectissmi(this);
+ if_objectissmi.If<HIsSmiAndBranch>(object);
+ if_objectissmi.Then();
+ {
+ // Compute hash for smi similar to smi_get_hash().
+ HValue* hash = Add<HBitwise>(Token::BIT_AND, object, mask);
+
+ // Load the key.
+ HValue* key_index = Add<HShl>(hash, graph()->GetConstant1());
+ HValue* key = AddFastElementAccess(number_string_cache, key_index,
+ NULL, NULL, FAST_ELEMENTS, false,
+ ALLOW_RETURN_HOLE, STANDARD_STORE);
+
+ // Check if object == key.
+ IfBuilder if_objectiskey(this);
+ if_objectiskey.If<HCompareObjectEqAndBranch>(key, object);
+ if_objectiskey.Then();
+ {
+ // Make the key_index available.
+ Push(key_index);
+ }
+ if_objectiskey.JoinContinuation(&found);
+ }
+ if_objectissmi.Else();
+ {
+ // Check if object is a heap number.
+ IfBuilder if_objectisnumber(this);
+ if_objectisnumber.If<HCompareMap>(
+ object, isolate()->factory()->heap_number_map());
+ if_objectisnumber.Then();
+ {
+ // Compute hash for heap number similar to double_get_hash().
+ HValue* low = Add<HLoadNamedField>(
+ object, HObjectAccess::ForHeapNumberValueLowestBits());
+ HValue* high = Add<HLoadNamedField>(
+ object, HObjectAccess::ForHeapNumberValueHighestBits());
+ HValue* hash = Add<HBitwise>(Token::BIT_XOR, low, high);
+ hash = Add<HBitwise>(Token::BIT_AND, hash, mask);
+
+ // Load the key.
+ HValue* key_index = Add<HShl>(hash, graph()->GetConstant1());
+ HValue* key = AddFastElementAccess(number_string_cache, key_index,
+ NULL, NULL, FAST_ELEMENTS, false,
+ ALLOW_RETURN_HOLE, STANDARD_STORE);
+
+ // Check if key is a heap number.
+ IfBuilder if_keyisnumber(this);
+ if_keyisnumber.IfNot<HIsSmiAndBranch>(key);
+ if_keyisnumber.AndIf<HCompareMap>(
+ key, isolate()->factory()->heap_number_map());
+ if_keyisnumber.Then();
+ {
+ // Check if values of key and object match.
+ IfBuilder if_keyeqobject(this);
+ if_keyeqobject.If<HCompareNumericAndBranch>(
+ Add<HLoadNamedField>(key, HObjectAccess::ForHeapNumberValue()),
+ Add<HLoadNamedField>(object,
HObjectAccess::ForHeapNumberValue()),
+ Token::EQ);
+ if_keyeqobject.Then();
+ {
+ // Make the key_index available.
+ Push(key_index);
+ }
+ if_keyeqobject.JoinContinuation(&found);
+ }
+ if_keyisnumber.JoinContinuation(&found);
+ }
+ if_objectisnumber.JoinContinuation(&found);
+ }
+ if_objectissmi.End();
+
+ // Check for cache hit.
+ IfBuilder if_found(this, &found);
+ if_found.Then();
+
+ // Load the value in case of cache hit.
+ HValue* key_index = Pop();
+ HValue* value_index = Add<HAdd>(key_index, graph()->GetConstant1());
+ HValue* value = AddFastElementAccess(number_string_cache, value_index,
+ NULL, NULL, FAST_ELEMENTS, false,
+ ALLOW_RETURN_HOLE, STANDARD_STORE);
+ AddIncrementCounter(isolate()->counters()->number_to_string_native());
+
+ if_found.CaptureContinuation(continuation);
+
+ // The value is only available in true branch of continuation.
+ return value;
+}
+
+
+HValue* HGraphBuilder::BuildNumberToString(HValue* number) {
+ NoObservableSideEffectsScope scope(this);
+
+ // Lookup the number in the number string cache.
+ HIfContinuation continuation;
+ HValue* value = BuildLookupNumberStringCache(number, &continuation);
+ IfBuilder if_found(this, &continuation);
+ if_found.Then();
+
+ // Cache hit.
+ Push(value);
+
+ if_found.Else();
+
+ // Cache miss, fallback to runtime.
+ Add<HPushArgument>(number);
+ Push(Add<HCallRuntime>(
+ isolate()->factory()->empty_string(),
+ Runtime::FunctionForId(Runtime::kNumberToStringSkipCache),
+ 1));
+
+ if_found.End();
+
+ return Pop();
+}
HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
@@ -9009,12 +9145,10 @@
// Fast support for number to string.
void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
ASSERT_EQ(1, call->arguments()->length());
- CHECK_ALIVE(VisitArgumentList(call->arguments()));
- HValue* context = environment()->context();
- HCallStub* result =
- new(zone()) HCallStub(context, CodeStub::NumberToString, 1);
- Drop(1);
- return ast_context()->ReturnInstruction(result, call->id());
+ CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+ HValue* number = Pop();
+ HValue* result = BuildNumberToString(number);
+ return ast_context()->ReturnValue(result);
}
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Fri Sep 20 10:47:09 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.h Mon Sep 23 10:58:45 2013 UTC
@@ -1237,6 +1237,15 @@
ElementsKind to_kind,
bool is_jsarray);
+ // Do lookup in the number string cache. If the object is not found
+ // in the cache, the false branch of the continuation is taken;
+ // otherwise the true branch is taken and the returned value contains
+ // the cache value for the object. The returned value must NOT be used
+ // on the false branch.
+ HValue* BuildLookupNumberStringCache(HValue* object,
+ HIfContinuation* continuation);
+ HValue* BuildNumberToString(HValue* number);
+
HInstruction* BuildUncheckedMonomorphicElementAccess(
HValue* checked_object,
HValue* key,
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Fri Sep 20 09:27:40
2013 UTC
+++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Mon Sep 23 10:58:45
2013 UTC
@@ -62,6 +62,16 @@
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
}
+
+
+void NumberToStringStub::InitializeInterfaceDescriptor(
+ Isolate* isolate,
+ CodeStubInterfaceDescriptor* descriptor) {
+ static Register registers[] = { eax };
+ descriptor->register_param_count_ = 1;
+ descriptor->register_params_ = registers;
+ descriptor->deoptimization_handler_ = NULL;
+}
void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
@@ -3765,21 +3775,6 @@
__ bind(&slowcase);
__ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1);
}
-
-
-void NumberToStringStub::Generate(MacroAssembler* masm) {
- Label runtime;
-
- __ mov(ebx, Operand(esp, kPointerSize));
-
- // Generate code to lookup number in the number string cache.
- __ LookupNumberStringCache(ebx, eax, ecx, edx, &runtime);
- __ ret(1 * kPointerSize);
-
- __ bind(&runtime);
- // Handle number to string in the runtime system if not found in the
cache.
- __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1);
-}
static int NegativeComparisonResult(Condition cc) {
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.h Thu Sep 19 06:07:23
2013 UTC
+++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.h Mon Sep 23 10:58:45
2013 UTC
@@ -217,18 +217,6 @@
};
-class NumberToStringStub: public PlatformCodeStub {
- public:
- NumberToStringStub() { }
-
- private:
- Major MajorKey() { return NumberToString; }
- int MinorKey() { return 0; }
-
- void Generate(MacroAssembler* masm);
-};
-
-
class NameDictionaryLookupStub: public PlatformCodeStub {
public:
enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Thu Sep 19
09:08:08 2013 UTC
+++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Mon Sep 23
10:58:45 2013 UTC
@@ -3549,8 +3549,8 @@
ZoneList<Expression*>* args = expr->arguments();
ASSERT_EQ(args->length(), 1);
- // Load the argument on the stack and call the stub.
- VisitForStackValue(args->at(0));
+ // Load the argument into eax and call the stub.
+ VisitForAccumulatorValue(args->at(0));
NumberToStringStub stub;
__ CallStub(&stub);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri Sep 20
12:32:31 2013 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon Sep 23
10:58:45 2013 UTC
@@ -1365,11 +1365,6 @@
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
break;
}
- case CodeStub::NumberToString: {
- NumberToStringStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
- break;
- }
case CodeStub::StringCompare: {
StringCompareStub stub;
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
=======================================
--- /branches/bleeding_edge/src/x64/code-stubs-x64.cc Fri Sep 20 09:27:40
2013 UTC
+++ /branches/bleeding_edge/src/x64/code-stubs-x64.cc Mon Sep 23 10:58:45
2013 UTC
@@ -58,6 +58,16 @@
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
}
+
+
+void NumberToStringStub::InitializeInterfaceDescriptor(
+ Isolate* isolate,
+ CodeStubInterfaceDescriptor* descriptor) {
+ static Register registers[] = { rax };
+ descriptor->register_param_count_ = 1;
+ descriptor->register_params_ = registers;
+ descriptor->deoptimization_handler_ = NULL;
+}
void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
@@ -2907,22 +2917,6 @@
__ bind(&slowcase);
__ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1);
}
-
-
-void NumberToStringStub::Generate(MacroAssembler* masm) {
- Label runtime;
-
- StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
- __ movq(rbx, args.GetArgumentOperand(0));
-
- // Generate code to lookup number in the number string cache.
- __ LookupNumberStringCache(rbx, rax, r8, r9, &runtime);
- __ ret(1 * kPointerSize);
-
- __ bind(&runtime);
- // Handle number to string in the runtime system if not found in the
cache.
- __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1);
-}
static int NegativeComparisonResult(Condition cc) {
=======================================
--- /branches/bleeding_edge/src/x64/code-stubs-x64.h Thu Sep 19 06:07:23
2013 UTC
+++ /branches/bleeding_edge/src/x64/code-stubs-x64.h Mon Sep 23 10:58:45
2013 UTC
@@ -208,18 +208,6 @@
};
-class NumberToStringStub: public PlatformCodeStub {
- public:
- NumberToStringStub() { }
-
- private:
- Major MajorKey() { return NumberToString; }
- int MinorKey() { return 0; }
-
- void Generate(MacroAssembler* masm);
-};
-
-
class NameDictionaryLookupStub: public PlatformCodeStub {
public:
enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Thu Sep 19 09:08:08
2013 UTC
+++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Mon Sep 23 10:58:45
2013 UTC
@@ -3507,8 +3507,8 @@
ZoneList<Expression*>* args = expr->arguments();
ASSERT_EQ(args->length(), 1);
- // Load the argument on the stack and call the stub.
- VisitForStackValue(args->at(0));
+ // Load the argument into rax and call the stub.
+ VisitForAccumulatorValue(args->at(0));
NumberToStringStub stub;
__ CallStub(&stub);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Fri Sep 20
12:32:31 2013 UTC
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Sep 23
10:58:45 2013 UTC
@@ -973,11 +973,6 @@
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
break;
}
- case CodeStub::NumberToString: {
- NumberToStringStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
- break;
- }
case CodeStub::StringCompare: {
StringCompareStub stub;
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.