Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(532)

Unified Diff: src/code-stubs-hydrogen.cc

Issue 1266013006: [stubs] Unify (and optimize) implementation of ToObject. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/code-stubs-hydrogen.cc
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index fb46633f0b3c961f20931053ea2a26d24263e885..c97e3686091647451b4a056d7c5821d0e1820146 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -1657,6 +1657,156 @@ Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() {
}
+template <>
+HValue* CodeStubGraphBuilder<ToObjectStub>::BuildCodeStub() {
+ HValue* receiver = GetParameter(ToObjectDescriptor::kReceiverIndex);
+ // Determine the proper global constructor function required to wrap
+ // {receiver} into a JSValue, unless {receiver} is already a {JSReceiver}, in
+ // which case we just return it. Deopts to Runtime::kToObject if {receiver}
+ // is undefined or null.
+ IfBuilder receiver_is_smi(this);
+ receiver_is_smi.If<HIsSmiAndBranch>(receiver);
+ receiver_is_smi.Then();
+ {
+ // Load native context.
+ HValue* native_context = BuildGetNativeContext();
+
+ // Load global Number function.
+ HValue* constructor = Add<HLoadNamedField>(
+ native_context, nullptr,
+ HObjectAccess::ForContextSlot(Context::NUMBER_FUNCTION_INDEX));
+ Push(constructor);
+ }
+ receiver_is_smi.Else();
+ {
+ // Determine {receiver} map and instance type.
+ HValue* receiver_map =
+ Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap());
+ HValue* receiver_instance_type = Add<HLoadNamedField>(
+ receiver_map, nullptr, HObjectAccess::ForMapInstanceType());
+
+ // First check whether {receiver} is already a spec object (fast case).
+ IfBuilder receiver_is_not_spec_object(this);
+ receiver_is_not_spec_object.If<HCompareNumericAndBranch>(
+ receiver_instance_type, Add<HConstant>(FIRST_SPEC_OBJECT_TYPE),
+ Token::LT);
+ receiver_is_not_spec_object.Then();
+ {
+ // Load native context.
+ HValue* native_context = BuildGetNativeContext();
+
+ IfBuilder receiver_is_heap_number(this);
+ receiver_is_heap_number.If<HCompareNumericAndBranch>(
+ receiver_instance_type, Add<HConstant>(HEAP_NUMBER_TYPE), Token::EQ);
+ receiver_is_heap_number.Then();
+ {
+ // Load global Number function.
+ HValue* constructor = Add<HLoadNamedField>(
+ native_context, nullptr,
+ HObjectAccess::ForContextSlot(Context::NUMBER_FUNCTION_INDEX));
+ Push(constructor);
+ }
+ receiver_is_heap_number.Else();
+ {
+ // Load boolean map (we cannot decide based on instance type, because
+ // it's ODDBALL_TYPE, which would also include null and undefined).
+ HValue* boolean_map = Add<HLoadRoot>(Heap::kBooleanMapRootIndex);
+
+ IfBuilder receiver_is_boolean(this);
+ receiver_is_boolean.If<HCompareObjectEqAndBranch>(receiver_map,
+ boolean_map);
+ receiver_is_boolean.Then();
+ {
+ // Load global Boolean function.
+ HValue* constructor = Add<HLoadNamedField>(
+ native_context, nullptr,
+ HObjectAccess::ForContextSlot(Context::BOOLEAN_FUNCTION_INDEX));
+ Push(constructor);
+ }
+ receiver_is_boolean.Else();
+ {
+ IfBuilder receiver_is_string(this);
+ receiver_is_string.If<HCompareNumericAndBranch>(
+ receiver_instance_type, Add<HConstant>(FIRST_NONSTRING_TYPE),
+ Token::LT);
+ receiver_is_string.Then();
+ {
+ // Load global String function.
+ HValue* constructor = Add<HLoadNamedField>(
+ native_context, nullptr,
+ HObjectAccess::ForContextSlot(Context::STRING_FUNCTION_INDEX));
+ Push(constructor);
+ }
+ receiver_is_string.Else();
+ {
+ IfBuilder receiver_is_symbol(this);
+ receiver_is_symbol.If<HCompareNumericAndBranch>(
+ receiver_instance_type, Add<HConstant>(SYMBOL_TYPE), Token::EQ);
+ receiver_is_symbol.Then();
+ {
+ // Load global Symbol function.
+ HValue* constructor = Add<HLoadNamedField>(
+ native_context, nullptr, HObjectAccess::ForContextSlot(
+ Context::SYMBOL_FUNCTION_INDEX));
+ Push(constructor);
+ }
+ receiver_is_symbol.Else();
+ {
+ IfBuilder receiver_is_float32x4(this);
+ receiver_is_float32x4.If<HCompareNumericAndBranch>(
+ receiver_instance_type, Add<HConstant>(FLOAT32X4_TYPE),
+ Token::EQ);
+ receiver_is_float32x4.Then();
+ {
+ // Load global Float32x4 function.
+ HValue* constructor = Add<HLoadNamedField>(
+ native_context, nullptr,
+ HObjectAccess::ForContextSlot(
+ Context::FLOAT32X4_FUNCTION_INDEX));
+ Push(constructor);
+ }
+ receiver_is_float32x4.ElseDeopt(
+ Deoptimizer::kUndefinedOrNullInToObject);
+ receiver_is_float32x4.End();
+ }
+ receiver_is_symbol.End();
+ }
+ receiver_is_string.End();
+ }
+ receiver_is_boolean.End();
+ }
+ receiver_is_heap_number.End();
+ }
+ receiver_is_not_spec_object.Else();
+ receiver_is_not_spec_object.Return(receiver);
+ receiver_is_not_spec_object.End();
+ }
+ receiver_is_smi.End();
+ // Determine the initial map for the global constructor.
+ HValue* constructor = Pop();
+ HValue* constructor_initial_map = Add<HLoadNamedField>(
+ constructor, nullptr, HObjectAccess::ForPrototypeOrInitialMap());
+ // Allocate and initialize a JSValue wrapper.
+ HValue* value =
+ BuildAllocate(Add<HConstant>(JSValue::kSize), HType::JSObject(),
+ JS_VALUE_TYPE, HAllocationMode());
+ Add<HStoreNamedField>(value, HObjectAccess::ForMap(),
+ constructor_initial_map);
+ HValue* empty_fixed_array = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex);
+ Add<HStoreNamedField>(value, HObjectAccess::ForPropertiesPointer(),
+ empty_fixed_array);
+ Add<HStoreNamedField>(value, HObjectAccess::ForElementsPointer(),
+ empty_fixed_array);
+ Add<HStoreNamedField>(
+ value, HObjectAccess::ForObservableJSObjectOffset(JSValue::kValueOffset),
+ receiver);
+ return value;
+}
+
+
+Handle<Code> ToObjectStub::GenerateCode() { return DoGenerateCode(this); }
+
+
void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode(
HValue* js_function,
HValue* native_context,
« no previous file with comments | « src/code-stubs.cc ('k') | src/collection.js » ('j') | src/ia32/interface-descriptors-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698