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.

Reply via email to