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

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: Comment response. 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 | « no previous file | 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 = Add<HLoadKeyed>(
2073 array, start, static_cast<HValue*>(NULL), FAST_ELEMENTS);
2074 IfBuilder if_correct_map(this);
2075 if_correct_map.If<HCompareObjectEqAndBranch>(receiver_map, array_map);
2076 if_correct_map.Then();
2077 { TailCallHandler(receiver, name, array, start, slot, vector); }
2078 if_correct_map.Else();
2079 {
2080 // If our array has more elements, the ic is polymorphic. Look for the
2081 // receiver map in the rest of the array.
2082 HValue* length =
2083 AddLoadFixedArrayLength(array, static_cast<HValue*>(NULL));
2084 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement,
2085 constant_two);
2086 start = keyed_load ? constant_three : constant_two;
2087 HValue* key = builder.BeginBody(start, length, Token::LT);
2088 {
2089 HValue* array_map = Add<HLoadKeyed>(
2090 array, key, static_cast<HValue*>(NULL), FAST_ELEMENTS);
2091 IfBuilder if_correct_map(this);
Jakob Kummerow 2014/12/03 13:22:17 nit: please don't shadow variables. (There's alrea
mvstanton 2014/12/08 12:44:24 Done.
2092 if_correct_map.If<HCompareObjectEqAndBranch>(receiver_map, array_map);
2093 if_correct_map.Then();
2094 { TailCallHandler(receiver, name, array, key, slot, vector); }
2095 }
2096 builder.EndBody();
2097
2098 TailCallMiss(receiver, name, slot, vector, keyed_load);
Jakob Kummerow 2014/12/03 13:22:17 nit: drop this...
mvstanton 2014/12/08 12:44:24 Done.
2099 }
2100 if_correct_map.End();
2101 }
2102 if_receiver_heap_object.Else();
Jakob Kummerow 2014/12/03 13:22:17 ...and this, and let all control flow paths fall t
mvstanton 2014/12/08 12:44:24 Done. I removed these two and changed the caller B
2103 { TailCallMiss(receiver, name, slot, vector, keyed_load); }
2104 }
2105
2106
2006 template <> 2107 template <>
2007 HValue* CodeStubGraphBuilder<VectorLoadStub>::BuildCodeStub() { 2108 HValue* CodeStubGraphBuilder<VectorLoadStub>::BuildCodeStub() {
2008 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex); 2109 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex);
2009 Add<HDeoptimize>("Always deopt", Deoptimizer::EAGER); 2110 HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex);
2010 return receiver; 2111 HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex);
2112 HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex);
2113
2114 // If the feedback is an array, then the IC is in the monomorphic or
2115 // polymorphic state.
2116 HValue* feedback =
2117 Add<HLoadKeyed>(vector, slot, static_cast<HValue*>(NULL), FAST_ELEMENTS);
2118 IfBuilder array_checker(this);
2119 array_checker.If<HCompareMap>(feedback,
2120 isolate()->factory()->fixed_array_map());
2121 array_checker.Then();
2122 { HandleArrayCases(feedback, receiver, name, slot, vector, false); }
2123 array_checker.Else();
2124 {
2125 // Is the IC megamorphic?
2126 IfBuilder mega_checker(this);
2127 HConstant* megamorphic_symbol =
2128 Add<HConstant>(isolate()->factory()->megamorphic_symbol());
2129 mega_checker.If<HCompareObjectEqAndBranch>(feedback, megamorphic_symbol);
2130 mega_checker.Then();
2131 {
2132 // Probe the stub cache.
2133 Add<HTailCallThroughMegamorphicCache>(
2134 receiver, name, slot, vector,
2135 HTailCallThroughMegamorphicCache::ComputeFlags(false, false));
2136 }
2137 mega_checker.End();
2138
2139 TailCallMiss(receiver, name, slot, vector, false);
2140 }
2141 array_checker.End();
2142
2143 // We never get here.
2144 return graph()->GetConstant0();
2011 } 2145 }
2012 2146
2013 2147
2014 Handle<Code> VectorLoadStub::GenerateCode() { return DoGenerateCode(this); } 2148 Handle<Code> VectorLoadStub::GenerateCode() { return DoGenerateCode(this); }
2015 2149
2016 2150
2017 template <> 2151 template <>
2018 HValue* CodeStubGraphBuilder<VectorKeyedLoadStub>::BuildCodeStub() { 2152 HValue* CodeStubGraphBuilder<VectorKeyedLoadStub>::BuildCodeStub() {
2019 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex); 2153 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex);
2020 Add<HDeoptimize>("Always deopt", Deoptimizer::EAGER); 2154 HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex);
2021 return receiver; 2155 HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex);
2156 HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex);
2157 HConstant* zero = graph()->GetConstant0();
2158
2159 // If the feedback is an array, then the IC is in the monomorphic or
2160 // polymorphic state.
2161 HValue* feedback =
2162 Add<HLoadKeyed>(vector, slot, static_cast<HValue*>(NULL), FAST_ELEMENTS);
2163 IfBuilder array_checker(this);
2164 array_checker.If<HCompareMap>(feedback,
2165 isolate()->factory()->fixed_array_map());
2166 array_checker.Then();
2167 {
2168 // If feedback[0] is 0, then the IC has element handlers and name should be
2169 // a smi. If feedback[0] is a string, verify that it matches name.
2170 HValue* recorded_name = Add<HLoadKeyed>(
2171 feedback, zero, static_cast<HValue*>(NULL), FAST_ELEMENTS);
2172
2173 IfBuilder recorded_name_is_zero(this);
2174 recorded_name_is_zero.If<HCompareNumericAndBranch>(recorded_name, zero,
2175 Token::EQ);
2176 recorded_name_is_zero.Then();
2177 { Add<HCheckSmi>(name); }
2178 recorded_name_is_zero.Else();
2179 {
2180 IfBuilder strings_match(this);
2181 strings_match.IfNot<HCompareObjectEqAndBranch>(name, recorded_name);
2182 strings_match.Then();
2183 TailCallMiss(receiver, name, slot, vector, true);
2184 strings_match.End();
2185 }
2186 recorded_name_is_zero.End();
2187
2188 HandleArrayCases(feedback, receiver, name, slot, vector, true);
2189 }
2190 array_checker.Else();
2191 {
2192 // Check if the IC in generic state.
Jakob Kummerow 2014/12/03 13:22:17 nit: missing "is"
mvstanton 2014/12/08 12:44:24 wow, good eye :D
Jakob Kummerow 2014/12/09 16:59:27 Nah, just OCD ;-)
2193 IfBuilder generic_checker(this);
2194 HConstant* generic_symbol =
2195 Add<HConstant>(isolate()->factory()->generic_symbol());
2196 generic_checker.If<HCompareObjectEqAndBranch>(feedback, generic_symbol);
2197 generic_checker.Then();
2198 {
2199 // Tail-call to the generic KeyedLoadIC, treating it like a handler.
2200 Handle<Code> stub = KeyedLoadIC::generic_stub(isolate());
2201 HValue* constant_stub = Add<HConstant>(stub);
2202 LoadDescriptor descriptor(isolate());
2203 HValue* op_vals[] = {context(), receiver, name};
2204 // We never return here, it is a tail call.
Jakob Kummerow 2014/12/03 13:22:17 nit: move this comment after the call please.
mvstanton 2014/12/08 12:44:24 Done.
2205 Add<HCallWithDescriptor>(constant_stub, 0, descriptor,
2206 Vector<HValue*>(op_vals, 3), TAIL_CALL);
2207 }
2208 generic_checker.End();
2209
2210 TailCallMiss(receiver, name, slot, vector, true);
2211 }
2212 array_checker.End();
2213
2214 // We never get here.
2215 return zero;
2022 } 2216 }
2023 2217
2024 2218
2025 Handle<Code> VectorKeyedLoadStub::GenerateCode() { 2219 Handle<Code> VectorKeyedLoadStub::GenerateCode() {
2026 return DoGenerateCode(this); 2220 return DoGenerateCode(this);
2027 } 2221 }
2028 2222
2029 2223
2030 Handle<Code> MegamorphicLoadStub::GenerateCode() { 2224 Handle<Code> MegamorphicLoadStub::GenerateCode() {
2031 return DoGenerateCode(this); 2225 return DoGenerateCode(this);
2032 } 2226 }
2033 2227
2034 2228
2035 template <> 2229 template <>
2036 HValue* CodeStubGraphBuilder<MegamorphicLoadStub>::BuildCodeStub() { 2230 HValue* CodeStubGraphBuilder<MegamorphicLoadStub>::BuildCodeStub() {
2037 // The return address is on the stack.
2038 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex); 2231 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
2039 HValue* name = GetParameter(LoadDescriptor::kNameIndex); 2232 HValue* name = GetParameter(LoadDescriptor::kNameIndex);
2040 2233
2234 // We shouldn't generate this when FLAG_vector_ics is true because the
2235 // megamorphic case is handled as part of the default stub.
2236 DCHECK(!FLAG_vector_ics);
2237
2041 // Probe the stub cache. 2238 // Probe the stub cache.
2042 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( 2239 Add<HTailCallThroughMegamorphicCache>(receiver, name);
2043 Code::ComputeHandlerFlags(Code::LOAD_IC));
2044 Add<HTailCallThroughMegamorphicCache>(receiver, name, flags);
2045 2240
2046 // We never continue. 2241 // We never continue.
2047 return graph()->GetConstant0(); 2242 return graph()->GetConstant0();
2048 } 2243 }
2049 } } // namespace v8::internal 2244 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698