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

Side by Side Diff: src/hydrogen.cc

Issue 1276533003: [runtime] Store constructor function index on primitive maps. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix arm failures Created 5 years, 4 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 unified diff | Download patch
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/hydrogen.h" 5 #include "src/hydrogen.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 2029 matching lines...) Expand 10 before | Expand all | Expand 10 after
2040 graph()->CreateBasicBlock()); 2040 graph()->CreateBasicBlock());
2041 2041
2042 // Determine the proper global constructor function required to wrap 2042 // Determine the proper global constructor function required to wrap
2043 // {receiver} into a JSValue, unless {receiver} is already a {JSReceiver}, in 2043 // {receiver} into a JSValue, unless {receiver} is already a {JSReceiver}, in
2044 // which case we just return it. Deopts to Runtime::kToObject if {receiver} 2044 // which case we just return it. Deopts to Runtime::kToObject if {receiver}
2045 // is undefined or null. 2045 // is undefined or null.
2046 IfBuilder receiver_is_smi(this); 2046 IfBuilder receiver_is_smi(this);
2047 receiver_is_smi.If<HIsSmiAndBranch>(receiver); 2047 receiver_is_smi.If<HIsSmiAndBranch>(receiver);
2048 receiver_is_smi.Then(); 2048 receiver_is_smi.Then();
2049 { 2049 {
2050 // Load native context. 2050 // Use global Number function.
2051 HValue* native_context = BuildGetNativeContext(); 2051 Push(Add<HConstant>(Context::NUMBER_FUNCTION_INDEX));
2052
2053 // Load global Number function.
2054 HValue* constructor = Add<HLoadNamedField>(
2055 native_context, nullptr,
2056 HObjectAccess::ForContextSlot(Context::NUMBER_FUNCTION_INDEX));
2057 Push(constructor);
2058 } 2052 }
2059 receiver_is_smi.Else(); 2053 receiver_is_smi.Else();
2060 { 2054 {
2061 // Determine {receiver} map and instance type. 2055 // Determine {receiver} map and instance type.
2062 HValue* receiver_map = 2056 HValue* receiver_map =
2063 Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap()); 2057 Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap());
2064 HValue* receiver_instance_type = Add<HLoadNamedField>( 2058 HValue* receiver_instance_type = Add<HLoadNamedField>(
2065 receiver_map, nullptr, HObjectAccess::ForMapInstanceType()); 2059 receiver_map, nullptr, HObjectAccess::ForMapInstanceType());
2066 2060
2067 // First check whether {receiver} is already a spec object (fast case). 2061 // First check whether {receiver} is already a spec object (fast case).
2068 IfBuilder receiver_is_not_spec_object(this); 2062 IfBuilder receiver_is_not_spec_object(this);
2069 receiver_is_not_spec_object.If<HCompareNumericAndBranch>( 2063 receiver_is_not_spec_object.If<HCompareNumericAndBranch>(
2070 receiver_instance_type, Add<HConstant>(FIRST_SPEC_OBJECT_TYPE), 2064 receiver_instance_type, Add<HConstant>(FIRST_SPEC_OBJECT_TYPE),
2071 Token::LT); 2065 Token::LT);
2072 receiver_is_not_spec_object.Then(); 2066 receiver_is_not_spec_object.Then();
2073 { 2067 {
2074 // Load native context. 2068 // Load the constructor function index from the {receiver} map.
2075 HValue* native_context = BuildGetNativeContext(); 2069 HValue* constructor_function_index = Add<HLoadNamedField>(
2070 receiver_map, nullptr,
2071 HObjectAccess::ForMapInObjectPropertiesOrConstructorFunctionIndex());
2076 2072
2077 IfBuilder receiver_is_heap_number(this); 2073 // Check if {receiver} has a constructor (null and undefined have no
2078 receiver_is_heap_number.If<HCompareNumericAndBranch>( 2074 // constructors, so we deoptimize to the runtime to throw an exception).
2079 receiver_instance_type, Add<HConstant>(HEAP_NUMBER_TYPE), Token::EQ); 2075 IfBuilder constructor_function_index_is_invalid(this);
2080 receiver_is_heap_number.Then(); 2076 constructor_function_index_is_invalid.If<HCompareNumericAndBranch>(
2081 { 2077 constructor_function_index,
2082 // Load global Number function. 2078 Add<HConstant>(Map::kNoConstructorFunctionIndex), Token::EQ);
2083 HValue* constructor = Add<HLoadNamedField>( 2079 constructor_function_index_is_invalid.ThenDeopt(
2084 native_context, nullptr, 2080 Deoptimizer::kUndefinedOrNullInToObject);
2085 HObjectAccess::ForContextSlot(Context::NUMBER_FUNCTION_INDEX)); 2081 constructor_function_index_is_invalid.End();
2086 Push(constructor);
2087 }
2088 receiver_is_heap_number.Else();
2089 {
2090 // Load boolean map (we cannot decide based on instance type, because
2091 // it's ODDBALL_TYPE, which would also include null and undefined).
2092 HValue* boolean_map = Add<HLoadRoot>(Heap::kBooleanMapRootIndex);
2093 2082
2094 IfBuilder receiver_is_boolean(this); 2083 // Use the global constructor function.
2095 receiver_is_boolean.If<HCompareObjectEqAndBranch>(receiver_map, 2084 Push(constructor_function_index);
2096 boolean_map);
2097 receiver_is_boolean.Then();
2098 {
2099 // Load global Boolean function.
2100 HValue* constructor = Add<HLoadNamedField>(
2101 native_context, nullptr,
2102 HObjectAccess::ForContextSlot(Context::BOOLEAN_FUNCTION_INDEX));
2103 Push(constructor);
2104 }
2105 receiver_is_boolean.Else();
2106 {
2107 IfBuilder receiver_is_string(this);
2108 receiver_is_string.If<HCompareNumericAndBranch>(
2109 receiver_instance_type, Add<HConstant>(FIRST_NONSTRING_TYPE),
2110 Token::LT);
2111 receiver_is_string.Then();
2112 {
2113 // Load global String function.
2114 HValue* constructor = Add<HLoadNamedField>(
2115 native_context, nullptr,
2116 HObjectAccess::ForContextSlot(Context::STRING_FUNCTION_INDEX));
2117 Push(constructor);
2118 }
2119 receiver_is_string.Else();
2120 {
2121 IfBuilder receiver_is_symbol(this);
2122 receiver_is_symbol.If<HCompareNumericAndBranch>(
2123 receiver_instance_type, Add<HConstant>(SYMBOL_TYPE), Token::EQ);
2124 receiver_is_symbol.Then();
2125 {
2126 // Load global Symbol function.
2127 HValue* constructor = Add<HLoadNamedField>(
2128 native_context, nullptr, HObjectAccess::ForContextSlot(
2129 Context::SYMBOL_FUNCTION_INDEX));
2130 Push(constructor);
2131 }
2132 // TODO(bmeurer): Don't inline this into crankshaft code, as it will
2133 // deoptimize on all SIMD128 objects.
2134 receiver_is_symbol.ElseDeopt(
2135 Deoptimizer::kUndefinedOrNullInToObject);
2136 receiver_is_symbol.JoinContinuation(&wrap);
2137 }
2138 receiver_is_string.JoinContinuation(&wrap);
2139 }
2140 receiver_is_boolean.JoinContinuation(&wrap);
2141 }
2142 receiver_is_heap_number.JoinContinuation(&wrap);
2143 } 2085 }
2144 receiver_is_not_spec_object.JoinContinuation(&wrap); 2086 receiver_is_not_spec_object.JoinContinuation(&wrap);
2145 } 2087 }
2146 receiver_is_smi.JoinContinuation(&wrap); 2088 receiver_is_smi.JoinContinuation(&wrap);
2147 2089
2148 // Wrap the receiver if necessary. 2090 // Wrap the receiver if necessary.
2149 IfBuilder if_wrap(this, &wrap); 2091 IfBuilder if_wrap(this, &wrap);
2150 if_wrap.Then(); 2092 if_wrap.Then();
2151 { 2093 {
2094 // Grab the constructor function index.
2095 HValue* constructor_index = Pop();
2096
2097 // Load native context.
2098 HValue* native_context = BuildGetNativeContext();
2099
2152 // Determine the initial map for the global constructor. 2100 // Determine the initial map for the global constructor.
2153 HValue* constructor = Pop(); 2101 HValue* constructor = Add<HLoadKeyed>(native_context, constructor_index,
2102 nullptr, FAST_ELEMENTS);
2154 HValue* constructor_initial_map = Add<HLoadNamedField>( 2103 HValue* constructor_initial_map = Add<HLoadNamedField>(
2155 constructor, nullptr, HObjectAccess::ForPrototypeOrInitialMap()); 2104 constructor, nullptr, HObjectAccess::ForPrototypeOrInitialMap());
2156 // Allocate and initialize a JSValue wrapper. 2105 // Allocate and initialize a JSValue wrapper.
2157 HValue* value = 2106 HValue* value =
2158 BuildAllocate(Add<HConstant>(JSValue::kSize), HType::JSObject(), 2107 BuildAllocate(Add<HConstant>(JSValue::kSize), HType::JSObject(),
2159 JS_VALUE_TYPE, HAllocationMode()); 2108 JS_VALUE_TYPE, HAllocationMode());
2160 Add<HStoreNamedField>(value, HObjectAccess::ForMap(), 2109 Add<HStoreNamedField>(value, HObjectAccess::ForMap(),
2161 constructor_initial_map); 2110 constructor_initial_map);
2162 HValue* empty_fixed_array = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex); 2111 HValue* empty_fixed_array = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex);
2163 Add<HStoreNamedField>(value, HObjectAccess::ForPropertiesPointer(), 2112 Add<HStoreNamedField>(value, HObjectAccess::ForPropertiesPointer(),
(...skipping 4272 matching lines...) Expand 10 before | Expand all | Expand 10 after
6436 if (!LookupInPrototypes()) return false; 6385 if (!LookupInPrototypes()) return false;
6437 if (IsLoad()) return true; 6386 if (IsLoad()) return true;
6438 6387
6439 if (IsAccessorConstant()) return true; 6388 if (IsAccessorConstant()) return true;
6440 LookupTransition(*map_, *name_, NONE); 6389 LookupTransition(*map_, *name_, NONE);
6441 if (IsTransitionToData() && map_->unused_property_fields() > 0) { 6390 if (IsTransitionToData() && map_->unused_property_fields() > 0) {
6442 // Construct the object field access. 6391 // Construct the object field access.
6443 int descriptor = transition()->LastAdded(); 6392 int descriptor = transition()->LastAdded();
6444 int index = 6393 int index =
6445 transition()->instance_descriptors()->GetFieldIndex(descriptor) - 6394 transition()->instance_descriptors()->GetFieldIndex(descriptor) -
6446 map_->inobject_properties(); 6395 map_->GetInObjectProperties();
6447 PropertyDetails details = 6396 PropertyDetails details =
6448 transition()->instance_descriptors()->GetDetails(descriptor); 6397 transition()->instance_descriptors()->GetDetails(descriptor);
6449 Representation representation = details.representation(); 6398 Representation representation = details.representation();
6450 access_ = HObjectAccess::ForField(map_, index, representation, name_); 6399 access_ = HObjectAccess::ForField(map_, index, representation, name_);
6451 6400
6452 // Load field map for heap objects. 6401 // Load field map for heap objects.
6453 return LoadFieldMaps(transition()); 6402 return LoadFieldMaps(transition());
6454 } 6403 }
6455 return false; 6404 return false;
6456 } 6405 }
(...skipping 3499 matching lines...) Expand 10 before | Expand all | Expand 10 after
9956 9905
9957 HInstruction* call = 9906 HInstruction* call =
9958 PreProcessCall(New<HCallNew>(function, argument_count)); 9907 PreProcessCall(New<HCallNew>(function, argument_count));
9959 return ast_context()->ReturnInstruction(call, expr->id()); 9908 return ast_context()->ReturnInstruction(call, expr->id());
9960 } 9909 }
9961 } 9910 }
9962 9911
9963 9912
9964 void HOptimizedGraphBuilder::BuildInitializeInobjectProperties( 9913 void HOptimizedGraphBuilder::BuildInitializeInobjectProperties(
9965 HValue* receiver, Handle<Map> initial_map) { 9914 HValue* receiver, Handle<Map> initial_map) {
9966 if (initial_map->inobject_properties() != 0) { 9915 if (initial_map->GetInObjectProperties() != 0) {
9967 HConstant* undefined = graph()->GetConstantUndefined(); 9916 HConstant* undefined = graph()->GetConstantUndefined();
9968 for (int i = 0; i < initial_map->inobject_properties(); i++) { 9917 for (int i = 0; i < initial_map->GetInObjectProperties(); i++) {
9969 int property_offset = initial_map->GetInObjectPropertyOffset(i); 9918 int property_offset = initial_map->GetInObjectPropertyOffset(i);
9970 Add<HStoreNamedField>(receiver, HObjectAccess::ForMapAndOffset( 9919 Add<HStoreNamedField>(receiver, HObjectAccess::ForMapAndOffset(
9971 initial_map, property_offset), 9920 initial_map, property_offset),
9972 undefined); 9921 undefined);
9973 } 9922 }
9974 } 9923 }
9975 } 9924 }
9976 9925
9977 9926
9978 HValue* HGraphBuilder::BuildAllocateEmptyArrayBuffer(HValue* byte_length) { 9927 HValue* HGraphBuilder::BuildAllocateEmptyArrayBuffer(HValue* byte_length) {
(...skipping 1792 matching lines...) Expand 10 before | Expand all | Expand 10 after
11771 // Ensure that value is stored as smi. 11720 // Ensure that value is stored as smi.
11772 access = access.WithRepresentation(representation); 11721 access = access.WithRepresentation(representation);
11773 } else { 11722 } else {
11774 value_instruction = Add<HConstant>(value); 11723 value_instruction = Add<HConstant>(value);
11775 } 11724 }
11776 11725
11777 Add<HStoreNamedField>(object, access, value_instruction); 11726 Add<HStoreNamedField>(object, access, value_instruction);
11778 } 11727 }
11779 } 11728 }
11780 11729
11781 int inobject_properties = boilerplate_object->map()->inobject_properties(); 11730 int inobject_properties = boilerplate_object->map()->GetInObjectProperties();
11782 HInstruction* value_instruction = 11731 HInstruction* value_instruction =
11783 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); 11732 Add<HConstant>(isolate()->factory()->one_pointer_filler_map());
11784 for (int i = copied_fields; i < inobject_properties; i++) { 11733 for (int i = copied_fields; i < inobject_properties; i++) {
11785 DCHECK(boilerplate_object->IsJSObject()); 11734 DCHECK(boilerplate_object->IsJSObject());
11786 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); 11735 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i);
11787 HObjectAccess access = 11736 HObjectAccess access =
11788 HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset); 11737 HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset);
11789 Add<HStoreNamedField>(object, access, value_instruction); 11738 Add<HStoreNamedField>(object, access, value_instruction);
11790 } 11739 }
11791 } 11740 }
(...skipping 1700 matching lines...) Expand 10 before | Expand all | Expand 10 after
13492 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13441 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13493 } 13442 }
13494 13443
13495 #ifdef DEBUG 13444 #ifdef DEBUG
13496 graph_->Verify(false); // No full verify. 13445 graph_->Verify(false); // No full verify.
13497 #endif 13446 #endif
13498 } 13447 }
13499 13448
13500 } // namespace internal 13449 } // namespace internal
13501 } // namespace v8 13450 } // namespace v8
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698