Revision: 20811
Author: [email protected]
Date: Wed Apr 16 14:04:54 2014 UTC
Log: Handlify number-related allocators.
[email protected]
Review URL: https://codereview.chromium.org/240293002
http://code.google.com/p/v8/source/detail?r=20811
Modified:
/branches/bleeding_edge/src/factory.cc
/branches/bleeding_edge/src/factory.h
/branches/bleeding_edge/src/heap-inl.h
/branches/bleeding_edge/src/heap.cc
/branches/bleeding_edge/src/heap.h
=======================================
--- /branches/bleeding_edge/src/factory.cc Wed Apr 16 13:35:36 2014 UTC
+++ /branches/bleeding_edge/src/factory.cc Wed Apr 16 14:04:54 2014 UTC
@@ -6,6 +6,7 @@
#include "macro-assembler.h"
#include "isolate-inl.h"
+#include "v8conversions.h"
namespace v8 {
namespace internal {
@@ -722,10 +723,11 @@
Handle<CodeCache> Factory::NewCodeCache() {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateCodeCache(),
- CodeCache);
+ Handle<CodeCache> code_cache =
+ Handle<CodeCache>::cast(NewStruct(CODE_CACHE_TYPE));
+ code_cache->set_default_cache(*empty_fixed_array(), SKIP_WRITE_BARRIER);
+ code_cache->set_normal_type_cache(*undefined_value(),
SKIP_WRITE_BARRIER);
+ return code_cache;
}
@@ -1017,17 +1019,26 @@
Handle<Object> Factory::NewNumber(double value,
PretenureFlag pretenure) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->NumberFromDouble(value, pretenure), Object);
+ // 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.
+ if (IsMinusZero(value)) return NewHeapNumber(-0.0, pretenure);
+
+ int int_value = FastD2I(value);
+ if (value == int_value && Smi::IsValid(int_value)) {
+ return handle(Smi::FromInt(int_value), isolate());
+ }
+
+ // Materialize the value in the heap.
+ return NewHeapNumber(value, pretenure);
}
Handle<Object> Factory::NewNumberFromInt(int32_t value,
PretenureFlag pretenure) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->NumberFromInt32(value, pretenure), Object);
+ if (Smi::IsValid(value)) return handle(Smi::FromInt(value), isolate());
+ // Bypass NumberFromDouble to avoid various redundant checks.
+ return NewHeapNumber(FastI2D(value), pretenure);
}
@@ -1852,20 +1863,80 @@
return share;
}
+
+
+static inline int NumberCacheHash(Handle<FixedArray> cache,
+ Handle<Object> number) {
+ int mask = (cache->length() >> 1) - 1;
+ if (number->IsSmi()) {
+ return Handle<Smi>::cast(number)->value() & mask;
+ } else {
+ DoubleRepresentation rep(number->Number());
+ return
+ (static_cast<int>(rep.bits) ^ static_cast<int>(rep.bits >> 32)) &
mask;
+ }
+}
+
+
+Handle<Object> Factory::GetNumberStringCache(Handle<Object> number) {
+ DisallowHeapAllocation no_gc;
+ int hash = NumberCacheHash(number_string_cache(), number);
+ Object* key = number_string_cache()->get(hash * 2);
+ if (key == *number || (key->IsHeapNumber() && number->IsHeapNumber() &&
+ key->Number() == number->Number())) {
+ return Handle<String>(
+ String::cast(number_string_cache()->get(hash * 2 + 1)), isolate());
+ }
+ return undefined_value();
+}
+
+
+void Factory::SetNumberStringCache(Handle<Object> number,
+ Handle<String> string) {
+ int hash = NumberCacheHash(number_string_cache(), number);
+ if (number_string_cache()->get(hash * 2) != *undefined_value()) {
+ int full_size = isolate()->heap()->FullSizeNumberStringCacheLength();
+ if (number_string_cache()->length() != full_size) {
+ // The first time we have a hash collision, we move to the full sized
+ // number string cache. The idea is to have a small number string
+ // cache in the snapshot to keep boot-time memory usage down.
+ // If we expand the number string cache already while creating
+ // the snapshot then that didn't work out.
+ ASSERT(!Serializer::enabled() || FLAG_extra_code != NULL);
+ Handle<FixedArray> new_cache = NewFixedArray(full_size, TENURED);
+ isolate()->heap()->set_number_string_cache(*new_cache);
+ return;
+ }
+ }
+ number_string_cache()->set(hash * 2, *number);
+ number_string_cache()->set(hash * 2 + 1, *string);
+}
Handle<String> Factory::NumberToString(Handle<Object> number,
bool check_number_string_cache) {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->NumberToString(
- *number, check_number_string_cache),
- String);
-}
+ isolate()->counters()->number_to_string_runtime()->Increment();
+ if (check_number_string_cache) {
+ Handle<Object> cached = GetNumberStringCache(number);
+ if (!cached->IsUndefined()) return Handle<String>::cast(cached);
+ }
+ char arr[100];
+ Vector<char> buffer(arr, ARRAY_SIZE(arr));
+ const char* str;
+ if (number->IsSmi()) {
+ int num = Handle<Smi>::cast(number)->value();
+ str = IntToCString(num, buffer);
+ } else {
+ double num = Handle<HeapNumber>::cast(number)->value();
+ str = DoubleToCString(num, buffer);
+ }
-Handle<String> Factory::Uint32ToString(uint32_t value) {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->Uint32ToString(value), String);
+ // We tenure the allocated string since it is referenced from the
+ // number-string cache which lives in the old space.
+ Handle<String> js_string = NewStringFromOneByte(OneByteVector(str),
TENURED);
+ SetNumberStringCache(number, js_string);
+ return js_string;
}
=======================================
--- /branches/bleeding_edge/src/factory.h Wed Apr 16 13:35:36 2014 UTC
+++ /branches/bleeding_edge/src/factory.h Wed Apr 16 14:04:54 2014 UTC
@@ -283,6 +283,7 @@
Handle<ConstantPoolArray> array);
// Numbers (e.g. literals) are pretenured by the parser.
+ // The return value may be a smi or a heap number.
Handle<Object> NewNumber(double value,
PretenureFlag pretenure = NOT_TENURED);
@@ -500,7 +501,10 @@
Handle<String> NumberToString(Handle<Object> number,
bool check_number_string_cache = true);
- Handle<String> Uint32ToString(uint32_t value);
+
+ Handle<String> Uint32ToString(uint32_t value) {
+ return NumberToString(NewNumberFromUint(value));
+ }
enum ApiInstanceType {
JavaScriptObject,
@@ -645,6 +649,13 @@
Handle<MapCache> AddToMapCache(Handle<Context> context,
Handle<FixedArray> keys,
Handle<Map> map);
+
+ // Attempt to find the number in a small cache. If we finds it, return
+ // the string representation of the number. Otherwise return undefined.
+ Handle<Object> GetNumberStringCache(Handle<Object> number);
+
+ // Update the cache with a new number-string pair.
+ void SetNumberStringCache(Handle<Object> number, Handle<String> string);
};
} } // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/heap-inl.h Fri Apr 11 09:20:56 2014 UTC
+++ /branches/bleeding_edge/src/heap-inl.h Wed Apr 16 14:04:54 2014 UTC
@@ -267,14 +267,6 @@
}
return result;
}
-
-
-MaybeObject* Heap::NumberFromInt32(
- int32_t value, PretenureFlag pretenure) {
- if (Smi::IsValid(value)) return Smi::FromInt(value);
- // Bypass NumberFromDouble to avoid various redundant checks.
- return AllocateHeapNumber(FastI2D(value), pretenure);
-}
MaybeObject* Heap::NumberFromUint32(
=======================================
--- /branches/bleeding_edge/src/heap.cc Wed Apr 16 13:35:36 2014 UTC
+++ /branches/bleeding_edge/src/heap.cc Wed Apr 16 14:04:54 2014 UTC
@@ -2406,17 +2406,6 @@
return map;
}
-
-
-MaybeObject* Heap::AllocateCodeCache() {
- CodeCache* code_cache;
- { MaybeObject* maybe_code_cache = AllocateStruct(CODE_CACHE_TYPE);
- if (!maybe_code_cache->To(&code_cache)) return maybe_code_cache;
- }
- code_cache->set_default_cache(empty_fixed_array(), SKIP_WRITE_BARRIER);
- code_cache->set_normal_type_cache(undefined_value(), SKIP_WRITE_BARRIER);
- return code_cache;
-}
MaybeObject* Heap::AllocatePolymorphicCodeCache() {
@@ -3253,24 +3242,6 @@
// of entries.
return number_string_cache_size * 2;
}
-
-
-void Heap::AllocateFullSizeNumberStringCache() {
- // The idea is to have a small number string cache in the snapshot to
keep
- // boot-time memory usage down. If we expand the number string cache
already
- // while creating the snapshot then that didn't work out.
- ASSERT(!Serializer::enabled() || FLAG_extra_code != NULL);
- MaybeObject* maybe_obj =
- AllocateFixedArray(FullSizeNumberStringCacheLength(), TENURED);
- Object* new_cache;
- if (maybe_obj->ToObject(&new_cache)) {
- // We don't bother to repopulate the cache with entries from the old
cache.
- // It will be repopulated soon enough with new strings.
- set_number_string_cache(FixedArray::cast(new_cache));
- }
- // If allocation fails then we just return without doing anything. It
is only
- // a cache, so best effort is OK here.
-}
void Heap::FlushNumberStringCache() {
@@ -3282,100 +3253,6 @@
}
-static inline int double_get_hash(double d) {
- DoubleRepresentation rep(d);
- return static_cast<int>(rep.bits) ^ static_cast<int>(rep.bits >> 32);
-}
-
-
-static inline int smi_get_hash(Smi* smi) {
- return smi->value();
-}
-
-
-Object* Heap::GetNumberStringCache(Object* number) {
- int hash;
- int mask = (number_string_cache()->length() >> 1) - 1;
- if (number->IsSmi()) {
- hash = smi_get_hash(Smi::cast(number)) & mask;
- } else {
- hash = double_get_hash(number->Number()) & mask;
- }
- Object* key = number_string_cache()->get(hash * 2);
- if (key == number) {
- return String::cast(number_string_cache()->get(hash * 2 + 1));
- } else if (key->IsHeapNumber() &&
- number->IsHeapNumber() &&
- key->Number() == number->Number()) {
- return String::cast(number_string_cache()->get(hash * 2 + 1));
- }
- return undefined_value();
-}
-
-
-void Heap::SetNumberStringCache(Object* number, String* string) {
- int hash;
- int mask = (number_string_cache()->length() >> 1) - 1;
- if (number->IsSmi()) {
- hash = smi_get_hash(Smi::cast(number)) & mask;
- } else {
- hash = double_get_hash(number->Number()) & mask;
- }
- if (number_string_cache()->get(hash * 2) != undefined_value() &&
- number_string_cache()->length() !=
FullSizeNumberStringCacheLength()) {
- // The first time we have a hash collision, we move to the full sized
- // number string cache.
- AllocateFullSizeNumberStringCache();
- return;
- }
- number_string_cache()->set(hash * 2, number);
- number_string_cache()->set(hash * 2 + 1, string);
-}
-
-
-MaybeObject* Heap::NumberToString(Object* number,
- bool check_number_string_cache) {
- isolate_->counters()->number_to_string_runtime()->Increment();
- if (check_number_string_cache) {
- Object* cached = GetNumberStringCache(number);
- if (cached != undefined_value()) {
- return cached;
- }
- }
-
- char arr[100];
- Vector<char> buffer(arr, ARRAY_SIZE(arr));
- const char* str;
- if (number->IsSmi()) {
- int num = Smi::cast(number)->value();
- str = IntToCString(num, buffer);
- } else {
- double num = HeapNumber::cast(number)->value();
- str = DoubleToCString(num, buffer);
- }
-
- Object* js_string;
-
- // We tenure the allocated string since it is referenced from the
- // number-string cache which lives in the old space.
- MaybeObject* maybe_js_string =
- AllocateStringFromOneByte(CStrVector(str), TENURED);
- if (maybe_js_string->ToObject(&js_string)) {
- SetNumberStringCache(number, String::cast(js_string));
- }
- return maybe_js_string;
-}
-
-
-MaybeObject* Heap::Uint32ToString(uint32_t value,
- bool check_number_string_cache) {
- Object* number;
- MaybeObject* maybe = NumberFromUint32(value);
- if (!maybe->To<Object>(&number)) return maybe;
- return NumberToString(number, check_number_string_cache);
-}
-
-
MaybeObject* Heap::AllocateAllocationSitesScratchpad() {
MaybeObject* maybe_obj =
AllocateFixedArray(kAllocationSiteScratchpadSize, TENURED);
@@ -3511,24 +3388,6 @@
return FixedTypedArrayBase::cast(
roots_[RootIndexForEmptyFixedTypedArray(map->elements_kind())]);
}
-
-
-MaybeObject* Heap::NumberFromDouble(double value, 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.
- if (IsMinusZero(value)) {
- 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);
-}
MaybeObject* Heap::AllocateForeign(Address address, PretenureFlag
pretenure) {
=======================================
--- /branches/bleeding_edge/src/heap.h Wed Apr 16 13:35:36 2014 UTC
+++ /branches/bleeding_edge/src/heap.h Wed Apr 16 14:04:54 2014 UTC
@@ -755,9 +755,6 @@
MUST_USE_RESULT MaybeObject* AllocatePartialMap(InstanceType
instance_type,
int instance_size);
- // Allocates an empty code cache.
- MUST_USE_RESULT MaybeObject* AllocateCodeCache();
-
// Allocates an empty PolymorphicCodeCache.
MUST_USE_RESULT MaybeObject* AllocatePolymorphicCodeCache();
@@ -982,22 +979,10 @@
MUST_USE_RESULT MaybeObject* AllocateArgumentsObject(
Object* callee, int length);
- // Same as NewNumberFromDouble, but may return a preallocated/immutable
- // number object (e.g., minus_zero_value_, nan_value_)
- MUST_USE_RESULT MaybeObject* NumberFromDouble(
- double value, PretenureFlag pretenure = NOT_TENURED);
-
// Allocated a HeapNumber from value.
MUST_USE_RESULT MaybeObject* AllocateHeapNumber(
double value, PretenureFlag pretenure = NOT_TENURED);
- // Converts an int 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.
- MUST_USE_RESULT inline MaybeObject* NumberFromInt32(
- int32_t value, PretenureFlag pretenure = NOT_TENURED);
-
// Converts an int into either a Smi or a HeapNumber object.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the
allocation
// failed.
@@ -1367,13 +1352,6 @@
bool CreateApiObjects();
- // Attempt to find the number in a small cache. If we finds it, return
- // the string representation of the number. Otherwise return undefined.
- Object* GetNumberStringCache(Object* number);
-
- // Update the cache with a new number-string pair.
- void SetNumberStringCache(Object* number, String* str);
-
// Adjusts the amount of registered external memory.
// Returns the adjusted value.
inline int64_t AdjustAmountOfExternalAllocatedMemory(
@@ -1470,11 +1448,6 @@
// Generated code can treat direct references to this root as constant.
bool RootCanBeTreatedAsConstant(RootListIndex root_index);
- MUST_USE_RESULT MaybeObject* NumberToString(
- Object* number, bool check_number_string_cache = true);
- MUST_USE_RESULT MaybeObject* Uint32ToString(
- uint32_t value, bool check_number_string_cache = true);
-
Map* MapForFixedTypedArray(ExternalArrayType array_type);
RootListIndex RootIndexForFixedTypedArray(
ExternalArrayType array_type);
@@ -2119,9 +2092,6 @@
// Allocates a small number to string cache.
MUST_USE_RESULT MaybeObject* AllocateInitialNumberStringCache();
// Creates and installs the full-sized number string cache.
- void AllocateFullSizeNumberStringCache();
- // Get the length of the number to string cache based on the max
semispace
- // size.
int FullSizeNumberStringCacheLength();
// Flush the number to string cache.
void FlushNumberStringCache();
--
--
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/d/optout.