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

Side by Side Diff: src/code-stubs-hydrogen.cc

Issue 767743002: Hydrogen code stubs for vector-based ICs. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase. Created 6 years 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/arm64/lithium-codegen-arm64.cc ('k') | src/hydrogen.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/bailout-reason.h" 7 #include "src/bailout-reason.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/field-index.h" 9 #include "src/field-index.h"
10 #include "src/hydrogen.h" 10 #include "src/hydrogen.h"
11 #include "src/ic/ic.h"
11 #include "src/lithium.h" 12 #include "src/lithium.h"
12 13
13 namespace v8 { 14 namespace v8 {
14 namespace internal { 15 namespace internal {
15 16
16 17
17 static LChunk* OptimizeGraph(HGraph* graph) { 18 static LChunk* OptimizeGraph(HGraph* graph) {
18 DisallowHeapAllocation no_allocation; 19 DisallowHeapAllocation no_allocation;
19 DisallowHandleAllocation no_handles; 20 DisallowHandleAllocation no_handles;
20 DisallowHandleDereference no_deref; 21 DisallowHandleDereference no_deref;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 HValue* map_index); 93 HValue* map_index);
93 void BuildInstallCode(HValue* js_function, HValue* shared_info); 94 void BuildInstallCode(HValue* js_function, HValue* shared_info);
94 95
95 HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map, 96 HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map,
96 HValue* iterator, 97 HValue* iterator,
97 int field_offset); 98 int field_offset);
98 void BuildInstallFromOptimizedCodeMap(HValue* js_function, 99 void BuildInstallFromOptimizedCodeMap(HValue* js_function,
99 HValue* shared_info, 100 HValue* shared_info,
100 HValue* native_context); 101 HValue* native_context);
101 102
103 // Tail calls handler found at array[map_index + 1].
104 void TailCallHandler(HValue* receiver, HValue* name, HValue* array,
105 HValue* map_index, HValue* slot, HValue* vector);
106
107 // Tail calls handler_code.
108 void TailCallHandler(HValue* receiver, HValue* name, HValue* slot,
109 HValue* vector, HValue* handler_code);
110
111 void TailCallMiss(HValue* receiver, HValue* name, HValue* slot,
112 HValue* vector, bool keyed_load);
113
114 // Handle MONOMORPHIC and POLYMORPHIC LoadIC and KeyedLoadIC cases.
115 void HandleArrayCases(HValue* array, HValue* receiver, HValue* name,
116 HValue* slot, HValue* vector, bool keyed_load);
117
102 private: 118 private:
103 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); 119 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
104 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, 120 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
105 ElementsKind kind); 121 ElementsKind kind);
106 122
107 SmartArrayPointer<HParameter*> parameters_; 123 SmartArrayPointer<HParameter*> parameters_;
108 HValue* arguments_length_; 124 HValue* arguments_length_;
109 CompilationInfoWithZone info_; 125 CompilationInfoWithZone info_;
110 CodeStubDescriptor descriptor_; 126 CodeStubDescriptor descriptor_;
111 HContext* context_; 127 HContext* context_;
(...skipping 1884 matching lines...) Expand 10 before | Expand all | Expand 10 after
1996 2012
1997 return Pop(); 2013 return Pop();
1998 } 2014 }
1999 2015
2000 2016
2001 Handle<Code> KeyedLoadGenericStub::GenerateCode() { 2017 Handle<Code> KeyedLoadGenericStub::GenerateCode() {
2002 return DoGenerateCode(this); 2018 return DoGenerateCode(this);
2003 } 2019 }
2004 2020
2005 2021
2022 void CodeStubGraphBuilderBase::TailCallHandler(HValue* receiver, HValue* name,
2023 HValue* array, HValue* map_index,
2024 HValue* slot, HValue* vector) {
2025 // The handler is at array[map_index + 1]. Compute this with a custom offset
2026 // to HLoadKeyed.
2027 int offset =
2028 GetDefaultHeaderSizeForElementsKind(FAST_ELEMENTS) + kPointerSize;
2029 HValue* handler_code =
2030 Add<HLoadKeyed>(array, map_index, static_cast<HValue*>(NULL),
2031 FAST_ELEMENTS, NEVER_RETURN_HOLE, offset);
2032 TailCallHandler(receiver, name, slot, vector, handler_code);
2033 }
2034
2035
2036 void CodeStubGraphBuilderBase::TailCallHandler(HValue* receiver, HValue* name,
2037 HValue* slot, HValue* vector,
2038 HValue* handler_code) {
2039 VectorLoadICDescriptor descriptor(isolate());
2040 HValue* op_vals[] = {context(), receiver, name, slot, vector};
2041 Add<HCallWithDescriptor>(handler_code, 0, descriptor,
2042 Vector<HValue*>(op_vals, 5), TAIL_CALL);
2043 // We never return here, it is a tail call.
2044 }
2045
2046
2047 void CodeStubGraphBuilderBase::TailCallMiss(HValue* receiver, HValue* name,
2048 HValue* slot, HValue* vector,
2049 bool keyed_load) {
2050 DCHECK(FLAG_vector_ics);
2051 Add<HTailCallThroughMegamorphicCache>(
2052 receiver, name, slot, vector,
2053 HTailCallThroughMegamorphicCache::ComputeFlags(keyed_load, true));
2054 // We never return here, it is a tail call.
2055 }
2056
2057
2058 void CodeStubGraphBuilderBase::HandleArrayCases(HValue* array, HValue* receiver,
2059 HValue* name, HValue* slot,
2060 HValue* vector,
2061 bool keyed_load) {
2062 IfBuilder if_receiver_heap_object(this);
2063 if_receiver_heap_object.IfNot<HIsSmiAndBranch>(receiver);
2064 if_receiver_heap_object.Then();
2065 {
2066 HConstant* constant_two = Add<HConstant>(2);
2067 HConstant* constant_three = Add<HConstant>(3);
2068
2069 HValue* receiver_map = AddLoadMap(receiver, static_cast<HValue*>(NULL));
2070 HValue* start =
2071 keyed_load ? graph()->GetConstant1() : graph()->GetConstant0();
2072 HValue* array_map =
2073 Add<HLoadKeyed>(array, start, static_cast<HValue*>(NULL), FAST_ELEMENTS,
2074 ALLOW_RETURN_HOLE);
2075 IfBuilder if_correct_map(this);
2076 if_correct_map.If<HCompareObjectEqAndBranch>(receiver_map, array_map);
2077 if_correct_map.Then();
2078 { TailCallHandler(receiver, name, array, start, slot, vector); }
2079 if_correct_map.Else();
2080 {
2081 // If our array has more elements, the ic is polymorphic. Look for the
2082 // receiver map in the rest of the array.
2083 HValue* length =
2084 AddLoadFixedArrayLength(array, static_cast<HValue*>(NULL));
2085 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement,
2086 constant_two);
2087 start = keyed_load ? constant_three : constant_two;
2088 HValue* key = builder.BeginBody(start, length, Token::LT);
2089 {
2090 HValue* array_map =
2091 Add<HLoadKeyed>(array, key, static_cast<HValue*>(NULL),
2092 FAST_ELEMENTS, ALLOW_RETURN_HOLE);
2093 IfBuilder if_correct_poly_map(this);
2094 if_correct_poly_map.If<HCompareObjectEqAndBranch>(receiver_map,
2095 array_map);
2096 if_correct_poly_map.Then();
2097 { TailCallHandler(receiver, name, array, key, slot, vector); }
2098 }
2099 builder.EndBody();
2100 }
2101 if_correct_map.End();
2102 }
2103 }
2104
2105
2006 template <> 2106 template <>
2007 HValue* CodeStubGraphBuilder<VectorLoadStub>::BuildCodeStub() { 2107 HValue* CodeStubGraphBuilder<VectorLoadStub>::BuildCodeStub() {
2008 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex); 2108 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex);
2009 Add<HDeoptimize>("Always deopt", Deoptimizer::EAGER); 2109 HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex);
2010 return receiver; 2110 HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex);
2111 HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex);
2112
2113 // If the feedback is an array, then the IC is in the monomorphic or
2114 // polymorphic state.
2115 HValue* feedback = Add<HLoadKeyed>(vector, slot, static_cast<HValue*>(NULL),
2116 FAST_ELEMENTS, ALLOW_RETURN_HOLE);
2117 IfBuilder array_checker(this);
2118 array_checker.If<HCompareMap>(feedback,
2119 isolate()->factory()->fixed_array_map());
2120 array_checker.Then();
2121 { HandleArrayCases(feedback, receiver, name, slot, vector, false); }
2122 array_checker.Else();
2123 {
2124 // Is the IC megamorphic?
2125 IfBuilder mega_checker(this);
2126 HConstant* megamorphic_symbol =
2127 Add<HConstant>(isolate()->factory()->megamorphic_symbol());
2128 mega_checker.If<HCompareObjectEqAndBranch>(feedback, megamorphic_symbol);
2129 mega_checker.Then();
2130 {
2131 // Probe the stub cache.
2132 Add<HTailCallThroughMegamorphicCache>(
2133 receiver, name, slot, vector,
2134 HTailCallThroughMegamorphicCache::ComputeFlags(false, false));
2135 }
2136 mega_checker.End();
2137 }
2138 array_checker.End();
2139
2140 TailCallMiss(receiver, name, slot, vector, false);
2141 return graph()->GetConstant0();
2011 } 2142 }
2012 2143
2013 2144
2014 Handle<Code> VectorLoadStub::GenerateCode() { return DoGenerateCode(this); } 2145 Handle<Code> VectorLoadStub::GenerateCode() { return DoGenerateCode(this); }
2015 2146
2016 2147
2017 template <> 2148 template <>
2018 HValue* CodeStubGraphBuilder<VectorKeyedLoadStub>::BuildCodeStub() { 2149 HValue* CodeStubGraphBuilder<VectorKeyedLoadStub>::BuildCodeStub() {
2019 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex); 2150 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex);
2020 Add<HDeoptimize>("Always deopt", Deoptimizer::EAGER); 2151 HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex);
2021 return receiver; 2152 HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex);
2153 HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex);
2154 HConstant* zero = graph()->GetConstant0();
2155
2156 // If the feedback is an array, then the IC is in the monomorphic or
2157 // polymorphic state.
2158 HValue* feedback = Add<HLoadKeyed>(vector, slot, static_cast<HValue*>(NULL),
2159 FAST_ELEMENTS, ALLOW_RETURN_HOLE);
2160 IfBuilder array_checker(this);
2161 array_checker.If<HCompareMap>(feedback,
2162 isolate()->factory()->fixed_array_map());
2163 array_checker.Then();
2164 {
2165 // If feedback[0] is 0, then the IC has element handlers and name should be
2166 // a smi. If feedback[0] is a string, verify that it matches name.
2167 HValue* recorded_name =
2168 Add<HLoadKeyed>(feedback, zero, static_cast<HValue*>(NULL),
2169 FAST_ELEMENTS, ALLOW_RETURN_HOLE);
2170
2171 IfBuilder recorded_name_is_zero(this);
2172 recorded_name_is_zero.If<HCompareObjectEqAndBranch>(recorded_name, zero);
2173 recorded_name_is_zero.Then();
2174 { Add<HCheckSmi>(name); }
2175 recorded_name_is_zero.Else();
2176 {
2177 IfBuilder strings_match(this);
2178 strings_match.IfNot<HCompareObjectEqAndBranch>(name, recorded_name);
2179 strings_match.Then();
2180 TailCallMiss(receiver, name, slot, vector, true);
2181 strings_match.End();
2182 }
2183 recorded_name_is_zero.End();
2184
2185 HandleArrayCases(feedback, receiver, name, slot, vector, true);
2186 }
2187 array_checker.Else();
2188 {
2189 // Check if the IC is in generic state.
2190 IfBuilder generic_checker(this);
2191 HConstant* generic_symbol =
2192 Add<HConstant>(isolate()->factory()->generic_symbol());
2193 generic_checker.If<HCompareObjectEqAndBranch>(feedback, generic_symbol);
2194 generic_checker.Then();
2195 {
2196 // Tail-call to the generic KeyedLoadIC, treating it like a handler.
2197 Handle<Code> stub = KeyedLoadIC::generic_stub(isolate());
2198 HValue* constant_stub = Add<HConstant>(stub);
2199 LoadDescriptor descriptor(isolate());
2200 HValue* op_vals[] = {context(), receiver, name};
2201 Add<HCallWithDescriptor>(constant_stub, 0, descriptor,
2202 Vector<HValue*>(op_vals, 3), TAIL_CALL);
2203 // We never return here, it is a tail call.
2204 }
2205 generic_checker.End();
2206 }
2207 array_checker.End();
2208
2209 TailCallMiss(receiver, name, slot, vector, true);
2210 return zero;
2022 } 2211 }
2023 2212
2024 2213
2025 Handle<Code> VectorKeyedLoadStub::GenerateCode() { 2214 Handle<Code> VectorKeyedLoadStub::GenerateCode() {
2026 return DoGenerateCode(this); 2215 return DoGenerateCode(this);
2027 } 2216 }
2028 2217
2029 2218
2030 Handle<Code> MegamorphicLoadStub::GenerateCode() { 2219 Handle<Code> MegamorphicLoadStub::GenerateCode() {
2031 return DoGenerateCode(this); 2220 return DoGenerateCode(this);
2032 } 2221 }
2033 2222
2034 2223
2035 template <> 2224 template <>
2036 HValue* CodeStubGraphBuilder<MegamorphicLoadStub>::BuildCodeStub() { 2225 HValue* CodeStubGraphBuilder<MegamorphicLoadStub>::BuildCodeStub() {
2037 // The return address is on the stack.
2038 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex); 2226 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
2039 HValue* name = GetParameter(LoadDescriptor::kNameIndex); 2227 HValue* name = GetParameter(LoadDescriptor::kNameIndex);
2040 2228
2229 // We shouldn't generate this when FLAG_vector_ics is true because the
2230 // megamorphic case is handled as part of the default stub.
2231 DCHECK(!FLAG_vector_ics);
2232
2041 // Probe the stub cache. 2233 // Probe the stub cache.
2042 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( 2234 Add<HTailCallThroughMegamorphicCache>(receiver, name);
2043 Code::ComputeHandlerFlags(Code::LOAD_IC));
2044 Add<HTailCallThroughMegamorphicCache>(receiver, name, flags);
2045 2235
2046 // We never continue. 2236 // We never continue.
2047 return graph()->GetConstant0(); 2237 return graph()->GetConstant0();
2048 } 2238 }
2049 } } // namespace v8::internal 2239 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm64/lithium-codegen-arm64.cc ('k') | src/hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698