OLD | NEW |
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...) Loading... |
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...) Loading... |
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...) Loading... |
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...) Loading... |
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...) Loading... |
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 |
OLD | NEW |