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

Side by Side Diff: src/ic/handler-compiler.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/ic/handler-compiler.h ('k') | src/ic/ia32/handler-compiler-ia32.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/ic/call-optimization.h" 7 #include "src/ic/call-optimization.h"
8 #include "src/ic/handler-compiler.h" 8 #include "src/ic/handler-compiler.h"
9 #include "src/ic/ic.h" 9 #include "src/ic/ic.h"
10 #include "src/ic/ic-inl.h" 10 #include "src/ic/ic-inl.h"
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 // Frontend for store uses the name register. It has to be restored before a 122 // Frontend for store uses the name register. It has to be restored before a
123 // miss. 123 // miss.
124 Register NamedStoreHandlerCompiler::FrontendHeader(Register object_reg, 124 Register NamedStoreHandlerCompiler::FrontendHeader(Register object_reg,
125 Handle<Name> name, 125 Handle<Name> name,
126 Label* miss) { 126 Label* miss) {
127 return CheckPrototypes(object_reg, this->name(), scratch1(), scratch2(), name, 127 return CheckPrototypes(object_reg, this->name(), scratch1(), scratch2(), name,
128 miss, SKIP_RECEIVER); 128 miss, SKIP_RECEIVER);
129 } 129 }
130 130
131 131
132 Register PropertyHandlerCompiler::Frontend(Register object_reg, 132 Register PropertyHandlerCompiler::Frontend(Handle<Name> name) {
133 Handle<Name> name) {
134 Label miss; 133 Label miss;
135 Register reg = FrontendHeader(object_reg, name, &miss); 134 if (IC::ICUseVector(kind())) {
135 PushVectorAndSlot();
136 }
137 Register reg = FrontendHeader(receiver(), name, &miss);
136 FrontendFooter(name, &miss); 138 FrontendFooter(name, &miss);
139 // The footer consumes the vector and slot from the stack if miss occurs.
140 if (IC::ICUseVector(kind())) {
141 DiscardVectorAndSlot();
142 }
137 return reg; 143 return reg;
138 } 144 }
139 145
140 146
141 void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name, 147 void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name,
142 Label* miss, 148 Label* miss,
143 Register scratch1, 149 Register scratch1,
144 Register scratch2) { 150 Register scratch2) {
145 Register holder_reg; 151 Register holder_reg;
146 Handle<Map> last_map; 152 Handle<Map> last_map;
(...skipping 25 matching lines...) Expand all
172 NameDictionary::kNotFound); 178 NameDictionary::kNotFound);
173 GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1, 179 GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1,
174 scratch2); 180 scratch2);
175 } 181 }
176 } 182 }
177 } 183 }
178 184
179 185
180 Handle<Code> NamedLoadHandlerCompiler::CompileLoadField(Handle<Name> name, 186 Handle<Code> NamedLoadHandlerCompiler::CompileLoadField(Handle<Name> name,
181 FieldIndex field) { 187 FieldIndex field) {
182 Register reg = Frontend(receiver(), name); 188 Register reg = Frontend(name);
183 __ Move(receiver(), reg); 189 __ Move(receiver(), reg);
184 LoadFieldStub stub(isolate(), field); 190 LoadFieldStub stub(isolate(), field);
185 GenerateTailCall(masm(), stub.GetCode()); 191 GenerateTailCall(masm(), stub.GetCode());
186 return GetCode(kind(), Code::FAST, name); 192 return GetCode(kind(), Code::FAST, name);
187 } 193 }
188 194
189 195
190 Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant(Handle<Name> name, 196 Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant(Handle<Name> name,
191 int constant_index) { 197 int constant_index) {
192 Register reg = Frontend(receiver(), name); 198 Register reg = Frontend(name);
193 __ Move(receiver(), reg); 199 __ Move(receiver(), reg);
194 LoadConstantStub stub(isolate(), constant_index); 200 LoadConstantStub stub(isolate(), constant_index);
195 GenerateTailCall(masm(), stub.GetCode()); 201 GenerateTailCall(masm(), stub.GetCode());
196 return GetCode(kind(), Code::FAST, name); 202 return GetCode(kind(), Code::FAST, name);
197 } 203 }
198 204
199 205
200 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( 206 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
201 Handle<Name> name) { 207 Handle<Name> name) {
202 Label miss; 208 Label miss;
209 if (IC::ICUseVector(kind())) {
210 DCHECK(kind() == Code::LOAD_IC);
211 PushVectorAndSlot();
212 }
203 NonexistentFrontendHeader(name, &miss, scratch2(), scratch3()); 213 NonexistentFrontendHeader(name, &miss, scratch2(), scratch3());
214 if (IC::ICUseVector(kind())) {
215 DiscardVectorAndSlot();
216 }
204 GenerateLoadConstant(isolate()->factory()->undefined_value()); 217 GenerateLoadConstant(isolate()->factory()->undefined_value());
205 FrontendFooter(name, &miss); 218 FrontendFooter(name, &miss);
206 return GetCode(kind(), Code::FAST, name); 219 return GetCode(kind(), Code::FAST, name);
207 } 220 }
208 221
209 222
210 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( 223 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
211 Handle<Name> name, Handle<ExecutableAccessorInfo> callback) { 224 Handle<Name> name, Handle<ExecutableAccessorInfo> callback) {
212 Register reg = Frontend(receiver(), name); 225 Register reg = Frontend(name);
213 GenerateLoadCallback(reg, callback); 226 GenerateLoadCallback(reg, callback);
214 return GetCode(kind(), Code::FAST, name); 227 return GetCode(kind(), Code::FAST, name);
215 } 228 }
216 229
217 230
218 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( 231 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
219 Handle<Name> name, const CallOptimization& call_optimization) { 232 Handle<Name> name, const CallOptimization& call_optimization) {
220 DCHECK(call_optimization.is_simple_api_call()); 233 DCHECK(call_optimization.is_simple_api_call());
221 Frontend(receiver(), name); 234 Frontend(name);
222 Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate()); 235 Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate());
223 GenerateFastApiCall(masm(), call_optimization, receiver_map, receiver(), 236 GenerateFastApiCall(masm(), call_optimization, receiver_map, receiver(),
224 scratch1(), false, 0, NULL); 237 scratch1(), false, 0, NULL);
225 return GetCode(kind(), Code::FAST, name); 238 return GetCode(kind(), Code::FAST, name);
226 } 239 }
227 240
228 241
242 void NamedLoadHandlerCompiler::InterceptorVectorSlotPush(Register holder_reg) {
243 if (IC::ICUseVector(kind())) {
244 if (holder_reg.is(receiver())) {
245 PushVectorAndSlot();
246 } else {
247 DCHECK(holder_reg.is(scratch1()));
248 PushVectorAndSlot(scratch2(), scratch3());
249 }
250 }
251 }
252
253
254 void NamedLoadHandlerCompiler::InterceptorVectorSlotPop(Register holder_reg,
255 PopMode mode) {
256 if (IC::ICUseVector(kind())) {
257 if (mode == DISCARD) {
258 DiscardVectorAndSlot();
259 } else {
260 if (holder_reg.is(receiver())) {
261 PopVectorAndSlot();
262 } else {
263 DCHECK(holder_reg.is(scratch1()));
264 PopVectorAndSlot(scratch2(), scratch3());
265 }
266 }
267 }
268 }
269
270
229 Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor( 271 Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor(
230 LookupIterator* it) { 272 LookupIterator* it) {
231 // So far the most popular follow ups for interceptor loads are FIELD and 273 // So far the most popular follow ups for interceptor loads are FIELD and
232 // ExecutableAccessorInfo, so inline only them. Other cases may be added 274 // ExecutableAccessorInfo, so inline only them. Other cases may be added
233 // later. 275 // later.
234 bool inline_followup = false; 276 bool inline_followup = false;
235 switch (it->state()) { 277 switch (it->state()) {
236 case LookupIterator::TRANSITION: 278 case LookupIterator::TRANSITION:
237 UNREACHABLE(); 279 UNREACHABLE();
238 case LookupIterator::ACCESS_CHECK: 280 case LookupIterator::ACCESS_CHECK:
(...skipping 10 matching lines...) Expand all
249 inline_followup = accessors->IsExecutableAccessorInfo(); 291 inline_followup = accessors->IsExecutableAccessorInfo();
250 if (!inline_followup) break; 292 if (!inline_followup) break;
251 Handle<ExecutableAccessorInfo> info = 293 Handle<ExecutableAccessorInfo> info =
252 Handle<ExecutableAccessorInfo>::cast(accessors); 294 Handle<ExecutableAccessorInfo>::cast(accessors);
253 inline_followup = info->getter() != NULL && 295 inline_followup = info->getter() != NULL &&
254 ExecutableAccessorInfo::IsCompatibleReceiverType( 296 ExecutableAccessorInfo::IsCompatibleReceiverType(
255 isolate(), info, type()); 297 isolate(), info, type());
256 } 298 }
257 } 299 }
258 300
259 Register reg = Frontend(receiver(), it->name()); 301 Label miss;
302 InterceptorVectorSlotPush(receiver());
303 Register reg = FrontendHeader(receiver(), it->name(), &miss);
304 FrontendFooter(it->name(), &miss);
305 InterceptorVectorSlotPop(reg);
306
260 if (inline_followup) { 307 if (inline_followup) {
261 // TODO(368): Compile in the whole chain: all the interceptors in 308 // TODO(368): Compile in the whole chain: all the interceptors in
262 // prototypes and ultimate answer. 309 // prototypes and ultimate answer.
263 GenerateLoadInterceptorWithFollowup(it, reg); 310 GenerateLoadInterceptorWithFollowup(it, reg);
264 } else { 311 } else {
265 GenerateLoadInterceptor(reg); 312 GenerateLoadInterceptor(reg);
266 } 313 }
267 return GetCode(kind(), Code::FAST, it->name()); 314 return GetCode(kind(), Code::FAST, it->name());
268 } 315 }
269 316
270 317
271 void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor( 318 void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
272 LookupIterator* it, Register interceptor_reg) { 319 LookupIterator* it, Register interceptor_reg) {
273 Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>()); 320 Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>());
274 321
275 set_type_for_object(holder()); 322 set_type_for_object(holder());
276 set_holder(real_named_property_holder); 323 set_holder(real_named_property_holder);
277 Register reg = Frontend(interceptor_reg, it->name()); 324
325 Label miss;
326 InterceptorVectorSlotPush(interceptor_reg);
327 Register reg = FrontendHeader(interceptor_reg, it->name(), &miss);
328 FrontendFooter(it->name(), &miss);
329 // We discard the vector and slot now because we don't miss below this point.
330 InterceptorVectorSlotPop(reg, DISCARD);
278 331
279 switch (it->state()) { 332 switch (it->state()) {
280 case LookupIterator::ACCESS_CHECK: 333 case LookupIterator::ACCESS_CHECK:
281 case LookupIterator::INTERCEPTOR: 334 case LookupIterator::INTERCEPTOR:
282 case LookupIterator::JSPROXY: 335 case LookupIterator::JSPROXY:
283 case LookupIterator::NOT_FOUND: 336 case LookupIterator::NOT_FOUND:
284 case LookupIterator::TRANSITION: 337 case LookupIterator::TRANSITION:
285 UNREACHABLE(); 338 UNREACHABLE();
286 case LookupIterator::DATA: { 339 case LookupIterator::DATA: {
287 DCHECK_EQ(FIELD, it->property_details().type()); 340 DCHECK_EQ(FIELD, it->property_details().type());
288 __ Move(receiver(), reg); 341 __ Move(receiver(), reg);
289 LoadFieldStub stub(isolate(), it->GetFieldIndex()); 342 LoadFieldStub stub(isolate(), it->GetFieldIndex());
290 GenerateTailCall(masm(), stub.GetCode()); 343 GenerateTailCall(masm(), stub.GetCode());
291 break; 344 break;
292 } 345 }
293 case LookupIterator::ACCESSOR: 346 case LookupIterator::ACCESSOR:
294 Handle<ExecutableAccessorInfo> info = 347 Handle<ExecutableAccessorInfo> info =
295 Handle<ExecutableAccessorInfo>::cast(it->GetAccessors()); 348 Handle<ExecutableAccessorInfo>::cast(it->GetAccessors());
296 DCHECK_NE(NULL, info->getter()); 349 DCHECK_NE(NULL, info->getter());
297 GenerateLoadCallback(reg, info); 350 GenerateLoadCallback(reg, info);
298 } 351 }
299 } 352 }
300 353
301 354
302 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter( 355 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter(
303 Handle<Name> name, Handle<JSFunction> getter) { 356 Handle<Name> name, Handle<JSFunction> getter) {
304 Frontend(receiver(), name); 357 Frontend(name);
305 GenerateLoadViaGetter(masm(), type(), receiver(), getter); 358 GenerateLoadViaGetter(masm(), type(), receiver(), getter);
306 return GetCode(kind(), Code::FAST, name); 359 return GetCode(kind(), Code::FAST, name);
307 } 360 }
308 361
309 362
310 // TODO(verwaest): Cleanup. holder() is actually the receiver. 363 // TODO(verwaest): Cleanup. holder() is actually the receiver.
311 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( 364 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
312 Handle<Map> transition, Handle<Name> name) { 365 Handle<Map> transition, Handle<Name> name) {
313 Label miss; 366 Label miss;
314 367
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 GenerateTailCall(masm(), stub.GetCode()); 435 GenerateTailCall(masm(), stub.GetCode());
383 436
384 __ bind(&miss); 437 __ bind(&miss);
385 TailCallBuiltin(masm(), MissBuiltin(kind())); 438 TailCallBuiltin(masm(), MissBuiltin(kind()));
386 return GetCode(kind(), Code::FAST, it->name()); 439 return GetCode(kind(), Code::FAST, it->name());
387 } 440 }
388 441
389 442
390 Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter( 443 Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter(
391 Handle<JSObject> object, Handle<Name> name, Handle<JSFunction> setter) { 444 Handle<JSObject> object, Handle<Name> name, Handle<JSFunction> setter) {
392 Frontend(receiver(), name); 445 Frontend(name);
393 GenerateStoreViaSetter(masm(), type(), receiver(), setter); 446 GenerateStoreViaSetter(masm(), type(), receiver(), setter);
394 447
395 return GetCode(kind(), Code::FAST, name); 448 return GetCode(kind(), Code::FAST, name);
396 } 449 }
397 450
398 451
399 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 452 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
400 Handle<JSObject> object, Handle<Name> name, 453 Handle<JSObject> object, Handle<Name> name,
401 const CallOptimization& call_optimization) { 454 const CallOptimization& call_optimization) {
402 Frontend(receiver(), name); 455 Frontend(name);
403 Register values[] = {value()}; 456 Register values[] = {value()};
404 GenerateFastApiCall(masm(), call_optimization, handle(object->map()), 457 GenerateFastApiCall(masm(), call_optimization, handle(object->map()),
405 receiver(), scratch1(), true, 1, values); 458 receiver(), scratch1(), true, 1, values);
406 return GetCode(kind(), Code::FAST, name); 459 return GetCode(kind(), Code::FAST, name);
407 } 460 }
408 461
409 462
410 #undef __ 463 #undef __
411 464
412 465
(...skipping 23 matching lines...) Expand all
436 DCHECK(elements_kind == DICTIONARY_ELEMENTS); 489 DCHECK(elements_kind == DICTIONARY_ELEMENTS);
437 cached_stub = LoadDictionaryElementStub(isolate()).GetCode(); 490 cached_stub = LoadDictionaryElementStub(isolate()).GetCode();
438 } 491 }
439 } 492 }
440 493
441 handlers->Add(cached_stub); 494 handlers->Add(cached_stub);
442 } 495 }
443 } 496 }
444 } 497 }
445 } // namespace v8::internal 498 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic/handler-compiler.h ('k') | src/ic/ia32/handler-compiler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698