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

Side by Side Diff: src/ic/handler-compiler.cc

Issue 1846963002: Use a dictionary-mode code cache on the map rather than a dual system. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comment Created 4 years, 8 months 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/ic/handler-compiler.h" 5 #include "src/ic/handler-compiler.h"
6 6
7 #include "src/field-type.h" 7 #include "src/field-type.h"
8 #include "src/ic/call-optimization.h" 8 #include "src/ic/call-optimization.h"
9 #include "src/ic/ic-inl.h" 9 #include "src/ic/ic-inl.h"
10 #include "src/ic/ic.h" 10 #include "src/ic/ic.h"
11 #include "src/isolate-inl.h" 11 #include "src/isolate-inl.h"
12 #include "src/profiler/cpu-profiler.h" 12 #include "src/profiler/cpu-profiler.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 16
17
18 Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name, 17 Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name,
19 Handle<Map> stub_holder, 18 Handle<Map> stub_holder,
20 Code::Kind kind, 19 Code::Kind kind,
21 CacheHolderFlag cache_holder, 20 CacheHolderFlag cache_holder) {
22 Code::StubType type) { 21 Code::Flags flags = Code::ComputeHandlerFlags(kind, cache_holder);
23 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder); 22 Code* code = stub_holder->LookupInCodeCache(*name, flags);
24 Object* probe = stub_holder->FindInCodeCache(*name, flags); 23 if (code == nullptr) return Handle<Code>();
25 if (probe->IsCode()) return handle(Code::cast(probe)); 24 return handle(code);
26 return Handle<Code>::null();
27 } 25 }
28 26
29 27
30 Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent( 28 Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent(
31 Handle<Name> name, Handle<Map> receiver_map) { 29 Handle<Name> name, Handle<Map> receiver_map) {
32 Isolate* isolate = name->GetIsolate(); 30 Isolate* isolate = name->GetIsolate();
33 if (receiver_map->prototype()->IsNull()) { 31 if (receiver_map->prototype()->IsNull()) {
34 // TODO(jkummerow/verwaest): If there is no prototype and the property 32 // TODO(jkummerow/verwaest): If there is no prototype and the property
35 // is nonexistent, introduce a builtin to handle this (fast properties 33 // is nonexistent, introduce a builtin to handle this (fast properties
36 // -> return undefined, dictionary properties -> do negative lookup). 34 // -> return undefined, dictionary properties -> do negative lookup).
(...skipping 22 matching lines...) Expand all
59 cache_name = name; 57 cache_name = name;
60 if (!current_map->has_hidden_prototype()) break; 58 if (!current_map->has_hidden_prototype()) break;
61 } 59 }
62 60
63 last = handle(JSObject::cast(current_map->prototype())); 61 last = handle(JSObject::cast(current_map->prototype()));
64 current_map = handle(last->map()); 62 current_map = handle(last->map());
65 } 63 }
66 // Compile the stub that is either shared for all names or 64 // Compile the stub that is either shared for all names or
67 // name specific if there are global objects involved. 65 // name specific if there are global objects involved.
68 Handle<Code> handler = PropertyHandlerCompiler::Find( 66 Handle<Code> handler = PropertyHandlerCompiler::Find(
69 cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST); 67 cache_name, stub_holder_map, Code::LOAD_IC, flag);
70 if (!handler.is_null()) return handler; 68 if (!handler.is_null()) return handler;
71 69
72 NamedLoadHandlerCompiler compiler(isolate, receiver_map, last, flag); 70 NamedLoadHandlerCompiler compiler(isolate, receiver_map, last, flag);
73 handler = compiler.CompileLoadNonexistent(cache_name); 71 handler = compiler.CompileLoadNonexistent(cache_name);
74 Map::UpdateCodeCache(stub_holder_map, cache_name, handler); 72 Map::UpdateCodeCache(stub_holder_map, cache_name, handler);
75 return handler; 73 return handler;
76 } 74 }
77 75
78 76
79 Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind, 77 Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind,
80 Code::StubType type,
81 Handle<Name> name) { 78 Handle<Name> name) {
82 Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder()); 79 Code::Flags flags = Code::ComputeHandlerFlags(kind, cache_holder());
83 Handle<Code> code = GetCodeWithFlags(flags, name); 80 Handle<Code> code = GetCodeWithFlags(flags, name);
84 PROFILE(isolate(), CodeCreateEvent(Logger::HANDLER_TAG, 81 PROFILE(isolate(), CodeCreateEvent(Logger::HANDLER_TAG,
85 AbstractCode::cast(*code), *name)); 82 AbstractCode::cast(*code), *name));
86 #ifdef DEBUG 83 #ifdef DEBUG
87 code->VerifyEmbeddedObjects(); 84 code->VerifyEmbeddedObjects();
88 #endif 85 #endif
89 return code; 86 return code;
90 } 87 }
91 88
92 89
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 } 184 }
188 } 185 }
189 186
190 187
191 Handle<Code> NamedLoadHandlerCompiler::CompileLoadField(Handle<Name> name, 188 Handle<Code> NamedLoadHandlerCompiler::CompileLoadField(Handle<Name> name,
192 FieldIndex field) { 189 FieldIndex field) {
193 Register reg = Frontend(name); 190 Register reg = Frontend(name);
194 __ Move(receiver(), reg); 191 __ Move(receiver(), reg);
195 LoadFieldStub stub(isolate(), field); 192 LoadFieldStub stub(isolate(), field);
196 GenerateTailCall(masm(), stub.GetCode()); 193 GenerateTailCall(masm(), stub.GetCode());
197 return GetCode(kind(), Code::FAST, name); 194 return GetCode(kind(), name);
198 } 195 }
199 196
200 197
201 Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant(Handle<Name> name, 198 Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant(Handle<Name> name,
202 int constant_index) { 199 int constant_index) {
203 Register reg = Frontend(name); 200 Register reg = Frontend(name);
204 __ Move(receiver(), reg); 201 __ Move(receiver(), reg);
205 LoadConstantStub stub(isolate(), constant_index); 202 LoadConstantStub stub(isolate(), constant_index);
206 GenerateTailCall(masm(), stub.GetCode()); 203 GenerateTailCall(masm(), stub.GetCode());
207 return GetCode(kind(), Code::FAST, name); 204 return GetCode(kind(), name);
208 } 205 }
209 206
210 207
211 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( 208 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
212 Handle<Name> name) { 209 Handle<Name> name) {
213 Label miss; 210 Label miss;
214 if (IC::ICUseVector(kind())) { 211 if (IC::ICUseVector(kind())) {
215 DCHECK(kind() == Code::LOAD_IC); 212 DCHECK(kind() == Code::LOAD_IC);
216 PushVectorAndSlot(); 213 PushVectorAndSlot();
217 } 214 }
218 NonexistentFrontendHeader(name, &miss, scratch2(), scratch3()); 215 NonexistentFrontendHeader(name, &miss, scratch2(), scratch3());
219 if (IC::ICUseVector(kind())) { 216 if (IC::ICUseVector(kind())) {
220 DiscardVectorAndSlot(); 217 DiscardVectorAndSlot();
221 } 218 }
222 GenerateLoadConstant(isolate()->factory()->undefined_value()); 219 GenerateLoadConstant(isolate()->factory()->undefined_value());
223 FrontendFooter(name, &miss); 220 FrontendFooter(name, &miss);
224 return GetCode(kind(), Code::FAST, name); 221 return GetCode(kind(), name);
225 } 222 }
226 223
227 224
228 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( 225 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
229 Handle<Name> name, Handle<AccessorInfo> callback) { 226 Handle<Name> name, Handle<AccessorInfo> callback) {
230 Register reg = Frontend(name); 227 Register reg = Frontend(name);
231 GenerateLoadCallback(reg, callback); 228 GenerateLoadCallback(reg, callback);
232 return GetCode(kind(), Code::FAST, name); 229 return GetCode(kind(), name);
233 } 230 }
234 231
235 232
236 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( 233 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
237 Handle<Name> name, const CallOptimization& call_optimization, 234 Handle<Name> name, const CallOptimization& call_optimization,
238 int accessor_index) { 235 int accessor_index) {
239 DCHECK(call_optimization.is_simple_api_call()); 236 DCHECK(call_optimization.is_simple_api_call());
240 Register holder = Frontend(name); 237 Register holder = Frontend(name);
241 GenerateApiAccessorCall(masm(), call_optimization, map(), receiver(), 238 GenerateApiAccessorCall(masm(), call_optimization, map(), receiver(),
242 scratch2(), false, no_reg, holder, accessor_index); 239 scratch2(), false, no_reg, holder, accessor_index);
243 return GetCode(kind(), Code::FAST, name); 240 return GetCode(kind(), name);
244 } 241 }
245 242
246 243
247 void NamedLoadHandlerCompiler::InterceptorVectorSlotPush(Register holder_reg) { 244 void NamedLoadHandlerCompiler::InterceptorVectorSlotPush(Register holder_reg) {
248 if (IC::ICUseVector(kind())) { 245 if (IC::ICUseVector(kind())) {
249 if (holder_reg.is(receiver())) { 246 if (holder_reg.is(receiver())) {
250 PushVectorAndSlot(); 247 PushVectorAndSlot();
251 } else { 248 } else {
252 DCHECK(holder_reg.is(scratch1())); 249 DCHECK(holder_reg.is(scratch1()));
253 PushVectorAndSlot(scratch2(), scratch3()); 250 PushVectorAndSlot(scratch2(), scratch3());
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 } 348 }
352 FrontendFooter(it->name(), &miss); 349 FrontendFooter(it->name(), &miss);
353 InterceptorVectorSlotPop(reg); 350 InterceptorVectorSlotPop(reg);
354 if (inline_followup) { 351 if (inline_followup) {
355 // TODO(368): Compile in the whole chain: all the interceptors in 352 // TODO(368): Compile in the whole chain: all the interceptors in
356 // prototypes and ultimate answer. 353 // prototypes and ultimate answer.
357 GenerateLoadInterceptorWithFollowup(it, reg); 354 GenerateLoadInterceptorWithFollowup(it, reg);
358 } else { 355 } else {
359 GenerateLoadInterceptor(reg); 356 GenerateLoadInterceptor(reg);
360 } 357 }
361 return GetCode(kind(), Code::FAST, it->name()); 358 return GetCode(kind(), it->name());
362 } 359 }
363 360
364 361
365 void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor( 362 void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
366 LookupIterator* it, Register interceptor_reg) { 363 LookupIterator* it, Register interceptor_reg) {
367 Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>()); 364 Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>());
368 365
369 Handle<Map> holder_map(holder()->map()); 366 Handle<Map> holder_map(holder()->map());
370 set_map(holder_map); 367 set_map(holder_map);
371 set_holder(real_named_property_holder); 368 set_holder(real_named_property_holder);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 } 406 }
410 } 407 }
411 } 408 }
412 409
413 410
414 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter( 411 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter(
415 Handle<Name> name, int accessor_index, int expected_arguments) { 412 Handle<Name> name, int accessor_index, int expected_arguments) {
416 Register holder = Frontend(name); 413 Register holder = Frontend(name);
417 GenerateLoadViaGetter(masm(), map(), receiver(), holder, accessor_index, 414 GenerateLoadViaGetter(masm(), map(), receiver(), holder, accessor_index,
418 expected_arguments, scratch2()); 415 expected_arguments, scratch2());
419 return GetCode(kind(), Code::FAST, name); 416 return GetCode(kind(), name);
420 } 417 }
421 418
422 419
423 // TODO(verwaest): Cleanup. holder() is actually the receiver. 420 // TODO(verwaest): Cleanup. holder() is actually the receiver.
424 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( 421 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
425 Handle<Map> transition, Handle<Name> name) { 422 Handle<Map> transition, Handle<Name> name) {
426 Label miss; 423 Label miss;
427 424
428 PushVectorAndSlot(); 425 PushVectorAndSlot();
429 426
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 StoreTransitionStub stub(isolate(), 496 StoreTransitionStub stub(isolate(),
500 FieldIndex::ForDescriptor(*transition, descriptor), 497 FieldIndex::ForDescriptor(*transition, descriptor),
501 representation, store_mode); 498 representation, store_mode);
502 GenerateTailCall(masm(), stub.GetCode()); 499 GenerateTailCall(masm(), stub.GetCode());
503 } 500 }
504 501
505 GenerateRestoreName(&miss, name); 502 GenerateRestoreName(&miss, name);
506 PopVectorAndSlot(); 503 PopVectorAndSlot();
507 TailCallBuiltin(masm(), MissBuiltin(kind())); 504 TailCallBuiltin(masm(), MissBuiltin(kind()));
508 505
509 return GetCode(kind(), Code::FAST, name); 506 return GetCode(kind(), name);
510 } 507 }
511 508
512 bool NamedStoreHandlerCompiler::RequiresFieldTypeChecks( 509 bool NamedStoreHandlerCompiler::RequiresFieldTypeChecks(
513 FieldType* field_type) const { 510 FieldType* field_type) const {
514 return field_type->IsClass(); 511 return field_type->IsClass();
515 } 512 }
516 513
517 514
518 Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) { 515 Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) {
519 Label miss; 516 Label miss;
520 DCHECK(it->representation().IsHeapObject()); 517 DCHECK(it->representation().IsHeapObject());
521 518
522 FieldType* field_type = *it->GetFieldType(); 519 FieldType* field_type = *it->GetFieldType();
523 bool need_save_restore = false; 520 bool need_save_restore = false;
524 if (RequiresFieldTypeChecks(field_type)) { 521 if (RequiresFieldTypeChecks(field_type)) {
525 need_save_restore = IC::ICUseVector(kind()); 522 need_save_restore = IC::ICUseVector(kind());
526 if (need_save_restore) PushVectorAndSlot(); 523 if (need_save_restore) PushVectorAndSlot();
527 GenerateFieldTypeChecks(field_type, value(), &miss); 524 GenerateFieldTypeChecks(field_type, value(), &miss);
528 if (need_save_restore) PopVectorAndSlot(); 525 if (need_save_restore) PopVectorAndSlot();
529 } 526 }
530 527
531 StoreFieldStub stub(isolate(), it->GetFieldIndex(), it->representation()); 528 StoreFieldStub stub(isolate(), it->GetFieldIndex(), it->representation());
532 GenerateTailCall(masm(), stub.GetCode()); 529 GenerateTailCall(masm(), stub.GetCode());
533 530
534 __ bind(&miss); 531 __ bind(&miss);
535 if (need_save_restore) PopVectorAndSlot(); 532 if (need_save_restore) PopVectorAndSlot();
536 TailCallBuiltin(masm(), MissBuiltin(kind())); 533 TailCallBuiltin(masm(), MissBuiltin(kind()));
537 return GetCode(kind(), Code::FAST, it->name()); 534 return GetCode(kind(), it->name());
538 } 535 }
539 536
540 537
541 Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter( 538 Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter(
542 Handle<JSObject> object, Handle<Name> name, int accessor_index, 539 Handle<JSObject> object, Handle<Name> name, int accessor_index,
543 int expected_arguments) { 540 int expected_arguments) {
544 Register holder = Frontend(name); 541 Register holder = Frontend(name);
545 GenerateStoreViaSetter(masm(), map(), receiver(), holder, accessor_index, 542 GenerateStoreViaSetter(masm(), map(), receiver(), holder, accessor_index,
546 expected_arguments, scratch2()); 543 expected_arguments, scratch2());
547 544
548 return GetCode(kind(), Code::FAST, name); 545 return GetCode(kind(), name);
549 } 546 }
550 547
551 548
552 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 549 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
553 Handle<JSObject> object, Handle<Name> name, 550 Handle<JSObject> object, Handle<Name> name,
554 const CallOptimization& call_optimization, int accessor_index) { 551 const CallOptimization& call_optimization, int accessor_index) {
555 Register holder = Frontend(name); 552 Register holder = Frontend(name);
556 GenerateApiAccessorCall(masm(), call_optimization, handle(object->map()), 553 GenerateApiAccessorCall(masm(), call_optimization, handle(object->map()),
557 receiver(), scratch2(), true, value(), holder, 554 receiver(), scratch2(), true, value(), holder,
558 accessor_index); 555 accessor_index);
559 return GetCode(kind(), Code::FAST, name); 556 return GetCode(kind(), name);
560 } 557 }
561 558
562 559
563 #undef __ 560 #undef __
564 561
565 void ElementHandlerCompiler::CompileElementHandlers( 562 void ElementHandlerCompiler::CompileElementHandlers(
566 MapHandleList* receiver_maps, CodeHandleList* handlers) { 563 MapHandleList* receiver_maps, CodeHandleList* handlers) {
567 for (int i = 0; i < receiver_maps->length(); ++i) { 564 for (int i = 0; i < receiver_maps->length(); ++i) {
568 Handle<Map> receiver_map = receiver_maps->at(i); 565 Handle<Map> receiver_map = receiver_maps->at(i);
569 Handle<Code> cached_stub; 566 Handle<Code> cached_stub;
(...skipping 27 matching lines...) Expand all
597 LoadICState state = LoadICState(kNoExtraICState); 594 LoadICState state = LoadICState(kNoExtraICState);
598 cached_stub = LoadDictionaryElementStub(isolate(), state).GetCode(); 595 cached_stub = LoadDictionaryElementStub(isolate(), state).GetCode();
599 } 596 }
600 } 597 }
601 598
602 handlers->Add(cached_stub); 599 handlers->Add(cached_stub);
603 } 600 }
604 } 601 }
605 } // namespace internal 602 } // namespace internal
606 } // namespace v8 603 } // namespace v8
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