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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9409 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ec587f8a
......@@ -1315,4 +1315,13 @@ void Factory::ConfigureInstance(Handle<FunctionTemplateInfo> desc,
}
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
......@@ -444,6 +444,11 @@ class Factory {
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); }
......
......@@ -2192,6 +2192,11 @@ bool Heap::CreateInitialObjects() {
}
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;
}
......
......@@ -126,6 +126,7 @@ inline Heap* _inline_get_heap_();
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 @@ inline Heap* _inline_get_heap_();
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;
......
......@@ -3146,6 +3146,16 @@ void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
}
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);
......
......@@ -3938,13 +3938,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
// 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->factory()->minus_infinity_symbol();
}
return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
return *isolate->factory()->infinity_symbol();
}
char* str = DoubleToRadixCString(value, radix);
MaybeObject* result =
......@@ -3960,13 +3960,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
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->factory()->minus_infinity_symbol();
}
return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
return *isolate->factory()->infinity_symbol();
}
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
int f = FastD2I(f_number);
......@@ -3985,13 +3985,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
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->factory()->minus_infinity_symbol();
}
return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
return *isolate->factory()->infinity_symbol();
}
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
int f = FastD2I(f_number);
......@@ -4010,13 +4010,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
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->factory()->minus_infinity_symbol();
}
return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
return *isolate->factory()->infinity_symbol();
}
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
int f = FastD2I(f_number);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment