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

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: Code comment response (mostly). 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
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_poly_map(this);
2092 if_correct_poly_map.If<HCompareObjectEqAndBranch>(receiver_map,
2093 array_map);
2094 if_correct_poly_map.Then();
2095 { TailCallHandler(receiver, name, array, key, slot, vector); }
2096 }
2097 builder.EndBody();
2098 }
2099 if_correct_map.End();
2100 }
2101 }
2102
2103
2006 template <> 2104 template <>
2007 HValue* CodeStubGraphBuilder<VectorLoadStub>::BuildCodeStub() { 2105 HValue* CodeStubGraphBuilder<VectorLoadStub>::BuildCodeStub() {
2008 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex); 2106 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex);
2009 Add<HDeoptimize>("Always deopt", Deoptimizer::EAGER); 2107 HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex);
2010 return receiver; 2108 HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex);
2109 HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex);
2110
2111 // If the feedback is an array, then the IC is in the monomorphic or
2112 // polymorphic state.
2113 HValue* feedback =
2114 Add<HLoadKeyed>(vector, slot, static_cast<HValue*>(NULL), FAST_ELEMENTS);
2115 IfBuilder array_checker(this);
2116 array_checker.If<HCompareMap>(feedback,
2117 isolate()->factory()->fixed_array_map());
2118 array_checker.Then();
2119 { HandleArrayCases(feedback, receiver, name, slot, vector, false); }
2120 array_checker.Else();
2121 {
2122 // Is the IC megamorphic?
2123 IfBuilder mega_checker(this);
2124 HConstant* megamorphic_symbol =
2125 Add<HConstant>(isolate()->factory()->megamorphic_symbol());
2126 mega_checker.If<HCompareObjectEqAndBranch>(feedback, megamorphic_symbol);
2127 mega_checker.Then();
2128 {
2129 // Probe the stub cache.
2130 Add<HTailCallThroughMegamorphicCache>(
2131 receiver, name, slot, vector,
2132 HTailCallThroughMegamorphicCache::ComputeFlags(false, false));
2133 }
2134 mega_checker.End();
2135 }
2136 array_checker.End();
2137
2138 TailCallMiss(receiver, name, slot, vector, false);
2139 return graph()->GetConstant0();
2011 } 2140 }
2012 2141
2013 2142
2014 Handle<Code> VectorLoadStub::GenerateCode() { return DoGenerateCode(this); } 2143 Handle<Code> VectorLoadStub::GenerateCode() { return DoGenerateCode(this); }
2015 2144
2016 2145
2017 template <> 2146 template <>
2018 HValue* CodeStubGraphBuilder<VectorKeyedLoadStub>::BuildCodeStub() { 2147 HValue* CodeStubGraphBuilder<VectorKeyedLoadStub>::BuildCodeStub() {
2019 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex); 2148 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex);
2020 Add<HDeoptimize>("Always deopt", Deoptimizer::EAGER); 2149 HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex);
2021 return receiver; 2150 HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex);
2151 HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex);
2152 HConstant* zero = graph()->GetConstant0();
2153
2154 // If the feedback is an array, then the IC is in the monomorphic or
2155 // polymorphic state.
2156 HValue* feedback =
2157 Add<HLoadKeyed>(vector, slot, static_cast<HValue*>(NULL), FAST_ELEMENTS);
2158 IfBuilder array_checker(this);
2159 array_checker.If<HCompareMap>(feedback,
2160 isolate()->factory()->fixed_array_map());
2161 array_checker.Then();
2162 {
2163 // If feedback[0] is 0, then the IC has element handlers and name should be
2164 // a smi. If feedback[0] is a string, verify that it matches name.
2165 HValue* recorded_name = Add<HLoadKeyed>(
2166 feedback, zero, static_cast<HValue*>(NULL), FAST_ELEMENTS);
2167
2168 IfBuilder recorded_name_is_zero(this);
2169 recorded_name_is_zero.If<HCompareNumericAndBranch>(recorded_name, zero,
2170 Token::EQ);
2171 recorded_name_is_zero.Then();
2172 { Add<HCheckSmi>(name); }
2173 recorded_name_is_zero.Else();
2174 {
2175 IfBuilder strings_match(this);
2176 strings_match.IfNot<HCompareObjectEqAndBranch>(name, recorded_name);
2177 strings_match.Then();
2178 TailCallMiss(receiver, name, slot, vector, true);
2179 strings_match.End();
2180 }
2181 recorded_name_is_zero.End();
2182
2183 HandleArrayCases(feedback, receiver, name, slot, vector, true);
2184 }
2185 array_checker.Else();
2186 {
2187 // Check if the IC is in generic state.
2188 IfBuilder generic_checker(this);
2189 HConstant* generic_symbol =
2190 Add<HConstant>(isolate()->factory()->generic_symbol());
2191 generic_checker.If<HCompareObjectEqAndBranch>(feedback, generic_symbol);
2192 generic_checker.Then();
2193 {
2194 // Tail-call to the generic KeyedLoadIC, treating it like a handler.
2195 Handle<Code> stub = KeyedLoadIC::generic_stub(isolate());
2196 HValue* constant_stub = Add<HConstant>(stub);
2197 LoadDescriptor descriptor(isolate());
2198 HValue* op_vals[] = {context(), receiver, name};
2199 Add<HCallWithDescriptor>(constant_stub, 0, descriptor,
2200 Vector<HValue*>(op_vals, 3), TAIL_CALL);
2201 // We never return here, it is a tail call.
2202 }
2203 generic_checker.End();
2204 }
2205 array_checker.End();
2206
2207 TailCallMiss(receiver, name, slot, vector, true);
2208 return zero;
2022 } 2209 }
2023 2210
2024 2211
2025 Handle<Code> VectorKeyedLoadStub::GenerateCode() { 2212 Handle<Code> VectorKeyedLoadStub::GenerateCode() {
2026 return DoGenerateCode(this); 2213 return DoGenerateCode(this);
2027 } 2214 }
2028 2215
2029 2216
2030 Handle<Code> MegamorphicLoadStub::GenerateCode() { 2217 Handle<Code> MegamorphicLoadStub::GenerateCode() {
2031 return DoGenerateCode(this); 2218 return DoGenerateCode(this);
2032 } 2219 }
2033 2220
2034 2221
2035 template <> 2222 template <>
2036 HValue* CodeStubGraphBuilder<MegamorphicLoadStub>::BuildCodeStub() { 2223 HValue* CodeStubGraphBuilder<MegamorphicLoadStub>::BuildCodeStub() {
2037 // The return address is on the stack.
2038 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex); 2224 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
2039 HValue* name = GetParameter(LoadDescriptor::kNameIndex); 2225 HValue* name = GetParameter(LoadDescriptor::kNameIndex);
2040 2226
2227 // We shouldn't generate this when FLAG_vector_ics is true because the
2228 // megamorphic case is handled as part of the default stub.
2229 DCHECK(!FLAG_vector_ics);
2230
2041 // Probe the stub cache. 2231 // Probe the stub cache.
2042 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( 2232 Add<HTailCallThroughMegamorphicCache>(receiver, name);
2043 Code::ComputeHandlerFlags(Code::LOAD_IC));
2044 Add<HTailCallThroughMegamorphicCache>(receiver, name, flags);
2045 2233
2046 // We never continue. 2234 // We never continue.
2047 return graph()->GetConstant0(); 2235 return graph()->GetConstant0();
2048 } 2236 }
2049 } } // namespace v8::internal 2237 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698