Revert "Turn the NumberToStringStub into a hydrogen stub."

This reverts commit 16874 for breaking the tests.

TBR=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/23440064

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16876 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
machenbach@chromium.org 2013-09-23 11:22:35 +00:00
parent c74587becd
commit 576515ebf3
17 changed files with 110 additions and 229 deletions

View File

@ -59,16 +59,6 @@ void ToNumberStub::InitializeInterfaceDescriptor(
} }
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( void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
Isolate* isolate, Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
@ -982,6 +972,22 @@ static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm,
} }
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, static void ICCompareStub_CheckInputType(MacroAssembler* masm,
Register input, Register input,
Register scratch, Register scratch,

View File

@ -257,6 +257,18 @@ class WriteInt32ToHeapNumberStub : public PlatformCodeStub {
}; };
class NumberToStringStub: public PlatformCodeStub {
public:
NumberToStringStub() { }
private:
Major MajorKey() { return NumberToString; }
int MinorKey() { return 0; }
void Generate(MacroAssembler* masm);
};
class RecordWriteStub: public PlatformCodeStub { class RecordWriteStub: public PlatformCodeStub {
public: public:
RecordWriteStub(Register object, RecordWriteStub(Register object,

View File

@ -3590,8 +3590,8 @@ void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) {
void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
ASSERT_EQ(args->length(), 1); ASSERT_EQ(args->length(), 1);
// Load the argument into r0 and call the stub. // Load the argument on the stack and call the stub.
VisitForAccumulatorValue(args->at(0)); VisitForStackValue(args->at(0));
NumberToStringStub stub; NumberToStringStub stub;
__ CallStub(&stub); __ CallStub(&stub);

View File

@ -1090,6 +1090,11 @@ void LCodeGen::DoCallStub(LCallStub* instr) {
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
break; break;
} }
case CodeStub::NumberToString: {
NumberToStringStub stub;
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
break;
}
case CodeStub::StringCompare: { case CodeStub::StringCompare: {
StringCompareStub stub; StringCompareStub stub;
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);

View File

@ -338,19 +338,6 @@ Handle<Code> ToNumberStub::GenerateCode(Isolate* isolate) {
} }
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 <> template <>
HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() {
Factory* factory = isolate()->factory(); Factory* factory = isolate()->factory();

View File

@ -464,25 +464,6 @@ class ToNumberStub: public HydrogenCodeStub {
}; };
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 { class FastNewClosureStub : public HydrogenCodeStub {
public: public:
explicit FastNewClosureStub(LanguageMode language_mode, bool is_generator) explicit FastNewClosureStub(LanguageMode language_mode, bool is_generator)

View File

@ -5667,18 +5667,6 @@ class HObjectAccess V8_FINAL {
kDouble, HeapNumber::kValueOffset, Representation::Double()); 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() { static HObjectAccess ForElementsPointer() {
return HObjectAccess(kElementsPointer, JSObject::kElementsOffset); return HObjectAccess(kElementsPointer, JSObject::kElementsOffset);
} }

View File

@ -1273,142 +1273,6 @@ void HGraphBuilder::BuildTransitionElementsKind(HValue* object,
} }
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( HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
HValue* checked_object, HValue* checked_object,
HValue* key, HValue* key,
@ -9145,10 +9009,12 @@ void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
// Fast support for number to string. // Fast support for number to string.
void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
ASSERT_EQ(1, call->arguments()->length()); ASSERT_EQ(1, call->arguments()->length());
CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); CHECK_ALIVE(VisitArgumentList(call->arguments()));
HValue* number = Pop(); HValue* context = environment()->context();
HValue* result = BuildNumberToString(number); HCallStub* result =
return ast_context()->ReturnValue(result); new(zone()) HCallStub(context, CodeStub::NumberToString, 1);
Drop(1);
return ast_context()->ReturnInstruction(result, call->id());
} }

View File

@ -1237,15 +1237,6 @@ class HGraphBuilder {
ElementsKind to_kind, ElementsKind to_kind,
bool is_jsarray); 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( HInstruction* BuildUncheckedMonomorphicElementAccess(
HValue* checked_object, HValue* checked_object,
HValue* key, HValue* key,

View File

@ -64,16 +64,6 @@ void ToNumberStub::InitializeInterfaceDescriptor(
} }
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( void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
Isolate* isolate, Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
@ -3777,6 +3767,21 @@ void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
} }
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) { static int NegativeComparisonResult(Condition cc) {
ASSERT(cc != equal); ASSERT(cc != equal);
ASSERT((cc == less) || (cc == less_equal) ASSERT((cc == less) || (cc == less_equal)

View File

@ -217,6 +217,18 @@ class StringCompareStub: public PlatformCodeStub {
}; };
class NumberToStringStub: public PlatformCodeStub {
public:
NumberToStringStub() { }
private:
Major MajorKey() { return NumberToString; }
int MinorKey() { return 0; }
void Generate(MacroAssembler* masm);
};
class NameDictionaryLookupStub: public PlatformCodeStub { class NameDictionaryLookupStub: public PlatformCodeStub {
public: public:
enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };

View File

@ -3549,8 +3549,8 @@ void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
ASSERT_EQ(args->length(), 1); ASSERT_EQ(args->length(), 1);
// Load the argument into eax and call the stub. // Load the argument on the stack and call the stub.
VisitForAccumulatorValue(args->at(0)); VisitForStackValue(args->at(0));
NumberToStringStub stub; NumberToStringStub stub;
__ CallStub(&stub); __ CallStub(&stub);

View File

@ -1365,6 +1365,11 @@ void LCodeGen::DoCallStub(LCallStub* instr) {
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
break; break;
} }
case CodeStub::NumberToString: {
NumberToStringStub stub;
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
break;
}
case CodeStub::StringCompare: { case CodeStub::StringCompare: {
StringCompareStub stub; StringCompareStub stub;
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);

View File

@ -60,16 +60,6 @@ void ToNumberStub::InitializeInterfaceDescriptor(
} }
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( void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
Isolate* isolate, Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
@ -2919,6 +2909,22 @@ void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
} }
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) { static int NegativeComparisonResult(Condition cc) {
ASSERT(cc != equal); ASSERT(cc != equal);
ASSERT((cc == less) || (cc == less_equal) ASSERT((cc == less) || (cc == less_equal)

View File

@ -208,6 +208,18 @@ class StringCompareStub: public PlatformCodeStub {
}; };
class NumberToStringStub: public PlatformCodeStub {
public:
NumberToStringStub() { }
private:
Major MajorKey() { return NumberToString; }
int MinorKey() { return 0; }
void Generate(MacroAssembler* masm);
};
class NameDictionaryLookupStub: public PlatformCodeStub { class NameDictionaryLookupStub: public PlatformCodeStub {
public: public:
enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };

View File

@ -3507,8 +3507,8 @@ void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
ASSERT_EQ(args->length(), 1); ASSERT_EQ(args->length(), 1);
// Load the argument into rax and call the stub. // Load the argument on the stack and call the stub.
VisitForAccumulatorValue(args->at(0)); VisitForStackValue(args->at(0));
NumberToStringStub stub; NumberToStringStub stub;
__ CallStub(&stub); __ CallStub(&stub);

View File

@ -973,6 +973,11 @@ void LCodeGen::DoCallStub(LCallStub* instr) {
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
break; break;
} }
case CodeStub::NumberToString: {
NumberToStringStub stub;
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
break;
}
case CodeStub::StringCompare: { case CodeStub::StringCompare: {
StringCompareStub stub; StringCompareStub stub;
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);