Simplify double to number convertion.

Review URL: http://codereview.chromium.org/1694004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4550 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
oleg@chromium.org 2010-04-29 14:01:37 +00:00
parent 6cff35044d
commit c98c930b1f
3 changed files with 22 additions and 62 deletions

View File

@ -1761,41 +1761,6 @@ void Heap::SetNumberStringCache(Object* number, String* string) {
}
Object* Heap::SmiOrNumberFromDouble(double value,
bool new_object,
PretenureFlag pretenure) {
// We need to distinguish the minus zero value and this cannot be
// done after conversion to int. Doing this by comparing bit
// patterns is faster than using fpclassify() et al.
static const DoubleRepresentation plus_zero(0.0);
static const DoubleRepresentation minus_zero(-0.0);
static const DoubleRepresentation nan(OS::nan_value());
ASSERT(minus_zero_value() != NULL);
ASSERT(sizeof(plus_zero.value) == sizeof(plus_zero.bits));
DoubleRepresentation rep(value);
if (rep.bits == plus_zero.bits) return Smi::FromInt(0); // not uncommon
if (rep.bits == minus_zero.bits) {
return new_object ? AllocateHeapNumber(-0.0, pretenure)
: minus_zero_value();
}
if (rep.bits == nan.bits) {
return new_object
? AllocateHeapNumber(OS::nan_value(), pretenure)
: nan_value();
}
// Try to represent the value as a tagged small integer.
int int_value = FastD2I(value);
if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
return Smi::FromInt(int_value);
}
// Materialize the value in the heap.
return AllocateHeapNumber(value, pretenure);
}
Object* Heap::NumberToString(Object* number, bool check_number_string_cache) {
Counters::number_to_string_runtime.Increment();
if (check_number_string_cache) {
@ -1853,17 +1818,24 @@ Heap::RootListIndex Heap::RootIndexForExternalArrayType(
}
Object* Heap::NewNumberFromDouble(double value, PretenureFlag pretenure) {
return SmiOrNumberFromDouble(value,
true /* number object must be new */,
pretenure);
}
Object* Heap::NumberFromDouble(double value, PretenureFlag pretenure) {
return SmiOrNumberFromDouble(value,
false /* use preallocated NaN, -0.0 */,
pretenure);
// We need to distinguish the minus zero value and this cannot be
// done after conversion to int. Doing this by comparing bit
// patterns is faster than using fpclassify() et al.
static const DoubleRepresentation minus_zero(-0.0);
DoubleRepresentation rep(value);
if (rep.bits == minus_zero.bits) {
return AllocateHeapNumber(-0.0, pretenure);
}
int int_value = FastD2I(value);
if (value == int_value && Smi::IsValid(int_value)) {
return Smi::FromInt(int_value);
}
// Materialize the value in the heap.
return AllocateHeapNumber(value, pretenure);
}

View File

@ -527,13 +527,6 @@ class Heap : public AllStatic {
// Please note this does not perform a garbage collection.
static Object* AllocateArgumentsObject(Object* callee, int length);
// Converts a double into either a Smi or a HeapNumber object.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this does not perform a garbage collection.
static Object* NewNumberFromDouble(double value,
PretenureFlag pretenure = NOT_TENURED);
// Same as NewNumberFromDouble, but may return a preallocated/immutable
// number object (e.g., minus_zero_value_, nan_value_)
static Object* NumberFromDouble(double value,
@ -1131,12 +1124,6 @@ class Heap : public AllStatic {
GarbageCollector collector,
GCTracer* tracer);
// Returns either a Smi or a Number object from 'value'. If 'new_object'
// is false, it may return a preallocated immutable object.
static Object* SmiOrNumberFromDouble(double value,
bool new_object,
PretenureFlag pretenure = NOT_TENURED);
// Allocate an uninitialized object in map space. The behavior is identical
// to Heap::AllocateRaw(size_in_bytes, MAP_SPACE), except that (a) it doesn't
// have to test the allocation space argument and (b) can reduce code size

View File

@ -5412,7 +5412,7 @@ static Object* Runtime_NumberDiv(Arguments args) {
CONVERT_DOUBLE_CHECKED(x, args[0]);
CONVERT_DOUBLE_CHECKED(y, args[1]);
return Heap::NewNumberFromDouble(x / y);
return Heap::NumberFromDouble(x / y);
}
@ -5424,8 +5424,8 @@ static Object* Runtime_NumberMod(Arguments args) {
CONVERT_DOUBLE_CHECKED(y, args[1]);
x = modulo(x, y);
// NewNumberFromDouble may return a Smi instead of a Number object
return Heap::NewNumberFromDouble(x);
// NumberFromDouble may return a Smi instead of a Number object
return Heap::NumberFromDouble(x);
}
@ -6079,7 +6079,8 @@ static Object* Runtime_RoundNumber(Arguments args) {
if (sign && value >= -0.5) return Heap::minus_zero_value();
return Heap::NumberFromDouble(floor(value + 0.5));
// Do not call NumberFromDouble() to avoid extra checks.
return Heap::AllocateHeapNumber(floor(value + 0.5));
}