Revision: 9409
Author:   [email protected]
Date:     Fri Sep 23 01:00:06 2011
Log:      Improve Hydrogen code for accessing undefined/null/Infinity.

In some special (but probably very common) cases we can do better than loading
from a global cell for these global properties by emitting the corresponding
constant directly. This opens up opportunities for further improvements, coming
in a separate CL...
Review URL: http://codereview.chromium.org/7992002
http://code.google.com/p/v8/source/detail?r=9409

Modified:
 /branches/bleeding_edge/src/factory.cc
 /branches/bleeding_edge/src/factory.h
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/heap.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/runtime.cc

=======================================
--- /branches/bleeding_edge/src/factory.cc      Thu Sep 22 04:30:04 2011
+++ /branches/bleeding_edge/src/factory.cc      Fri Sep 23 01:00:06 2011
@@ -1313,6 +1313,15 @@
     *pending_exception = false;
   }
 }
+
+
+Handle<Object> Factory::GlobalConstantFor(Handle<String> name) {
+  Heap* h = isolate()->heap();
+  if (name->Equals(h->undefined_symbol())) return undefined_value();
+  if (name->Equals(h->nan_symbol())) return nan_value();
+  if (name->Equals(h->infinity_symbol())) return infinity_value();
+  return Handle<Object>::null();
+}


 } }  // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/factory.h       Thu Sep 22 04:30:04 2011
+++ /branches/bleeding_edge/src/factory.h       Fri Sep 23 01:00:06 2011
@@ -444,6 +444,11 @@
                              JSRegExp::Flags flags,
                              int capture_count);

+ // Returns the value for a known global constant (a property of the global
+  // object which is neither configurable nor writable) like 'undefined'.
+  // Returns a null handle when the given name is unknown.
+  Handle<Object> GlobalConstantFor(Handle<String> name);
+
  private:
   Isolate* isolate() { return reinterpret_cast<Isolate*>(this); }

=======================================
--- /branches/bleeding_edge/src/heap.cc Thu Sep 22 10:10:40 2011
+++ /branches/bleeding_edge/src/heap.cc Fri Sep 23 01:00:06 2011
@@ -2192,6 +2192,11 @@
   }
   set_nan_value(obj);

+  { MaybeObject* maybe_obj = AllocateHeapNumber(V8_INFINITY, TENURED);
+    if (!maybe_obj->ToObject(&obj)) return false;
+  }
+  set_infinity_value(obj);
+
   { MaybeObject* maybe_obj = Allocate(oddball_map(), OLD_POINTER_SPACE);
     if (!maybe_obj->ToObject(&obj)) return false;
   }
=======================================
--- /branches/bleeding_edge/src/heap.h  Thu Sep 22 06:54:53 2011
+++ /branches/bleeding_edge/src/heap.h  Fri Sep 23 01:00:06 2011
@@ -126,6 +126,7 @@
V(Map, message_object_map, JSMessageObjectMap) \ V(Map, foreign_map, ForeignMap) \ V(Object, nan_value, NanValue) \ + V(Object, infinity_value, InfinityValue) \ V(Object, minus_zero_value, MinusZeroValue) \ V(Map, neander_map, NeanderMap) \ V(JSObject, message_listeners, MessageListeners) \
@@ -229,7 +230,9 @@
   V(closure_symbol, "(closure)")                                         \
   V(use_strict, "use strict")                                            \
   V(dot_symbol, ".")                                                     \
-  V(anonymous_function_symbol, "(anonymous function)")
+  V(anonymous_function_symbol, "(anonymous function)")                   \
+  V(infinity_symbol, "Infinity")                                         \
+  V(minus_infinity_symbol, "-Infinity")

 // Forward declarations.
 class GCTracer;
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Thu Sep 22 04:30:04 2011
+++ /branches/bleeding_edge/src/hydrogen.cc     Fri Sep 23 01:00:06 2011
@@ -3146,6 +3146,16 @@
   }
   switch (variable->location()) {
     case Variable::UNALLOCATED: {
+ // Handle known global constants like 'undefined' specially to avoid a
+      // load from a global cell for them.
+      Handle<Object> constant_value =
+          isolate()->factory()->GlobalConstantFor(variable->name());
+      if (!constant_value.is_null()) {
+        HConstant* instr =
+ new(zone()) HConstant(constant_value, Representation::Tagged());
+        return ast_context()->ReturnInstruction(instr, expr->id());
+      }
+
       LookupResult lookup;
       GlobalPropertyAccess type =
           LookupGlobalProperty(variable, &lookup, false);
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Thu Sep 22 10:12:41 2011
+++ /branches/bleeding_edge/src/runtime.cc      Fri Sep 23 01:00:06 2011
@@ -3938,13 +3938,13 @@
   // Slow case.
   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   if (isnan(value)) {
-    return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
+    return *isolate->factory()->nan_symbol();
   }
   if (isinf(value)) {
     if (value < 0) {
- return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity"));
-    }
- return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
+      return *isolate->factory()->minus_infinity_symbol();
+    }
+    return *isolate->factory()->infinity_symbol();
   }
   char* str = DoubleToRadixCString(value, radix);
   MaybeObject* result =
@@ -3960,13 +3960,13 @@

   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   if (isnan(value)) {
-    return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
+    return *isolate->factory()->nan_symbol();
   }
   if (isinf(value)) {
     if (value < 0) {
- return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity"));
-    }
- return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
+      return *isolate->factory()->minus_infinity_symbol();
+    }
+    return *isolate->factory()->infinity_symbol();
   }
   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   int f = FastD2I(f_number);
@@ -3985,13 +3985,13 @@

   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   if (isnan(value)) {
-    return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
+    return *isolate->factory()->nan_symbol();
   }
   if (isinf(value)) {
     if (value < 0) {
- return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity"));
-    }
- return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
+      return *isolate->factory()->minus_infinity_symbol();
+    }
+    return *isolate->factory()->infinity_symbol();
   }
   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   int f = FastD2I(f_number);
@@ -4010,13 +4010,13 @@

   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
   if (isnan(value)) {
-    return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
+    return *isolate->factory()->nan_symbol();
   }
   if (isinf(value)) {
     if (value < 0) {
- return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity"));
-    }
- return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
+      return *isolate->factory()->minus_infinity_symbol();
+    }
+    return *isolate->factory()->infinity_symbol();
   }
   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
   int f = FastD2I(f_number);

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to