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

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

Issue 483683005: Move IC code into a subdir and move ic-compilation related code from stub-cache into ic-compiler (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix BUILD.gn Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « src/ic/ic-compiler.h ('k') | src/ic/ic-inl.h » ('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 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/api.h" 7 #include "src/ic/ic-inl.h"
8 #include "src/arguments.h" 8 #include "src/ic/ic-compiler.h"
9 #include "src/ast.h" 9
10 #include "src/code-stubs.h"
11 #include "src/cpu-profiler.h"
12 #include "src/gdb-jit.h"
13 #include "src/ic-inl.h"
14 #include "src/stub-cache.h"
15 #include "src/type-info.h"
16 #include "src/vm-state-inl.h"
17 10
18 namespace v8 { 11 namespace v8 {
19 namespace internal { 12 namespace internal {
20 13
21 // -----------------------------------------------------------------------
22 // StubCache implementation.
23
24
25 StubCache::StubCache(Isolate* isolate)
26 : isolate_(isolate) { }
27
28
29 void StubCache::Initialize() {
30 DCHECK(IsPowerOf2(kPrimaryTableSize));
31 DCHECK(IsPowerOf2(kSecondaryTableSize));
32 Clear();
33 }
34
35
36 static Code::Flags CommonStubCacheChecks(Name* name, Map* map,
37 Code::Flags flags) {
38 flags = Code::RemoveTypeAndHolderFromFlags(flags);
39
40 // Validate that the name does not move on scavenge, and that we
41 // can use identity checks instead of structural equality checks.
42 DCHECK(!name->GetHeap()->InNewSpace(name));
43 DCHECK(name->IsUniqueName());
44
45 // The state bits are not important to the hash function because the stub
46 // cache only contains handlers. Make sure that the bits are the least
47 // significant so they will be the ones masked out.
48 DCHECK_EQ(Code::HANDLER, Code::ExtractKindFromFlags(flags));
49 STATIC_ASSERT((Code::ICStateField::kMask & 1) == 1);
50
51 // Make sure that the code type and cache holder are not included in the hash.
52 DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
53 DCHECK(Code::ExtractCacheHolderFromFlags(flags) == 0);
54
55 return flags;
56 }
57
58
59 Code* StubCache::Set(Name* name, Map* map, Code* code) {
60 Code::Flags flags = CommonStubCacheChecks(name, map, code->flags());
61
62 // Compute the primary entry.
63 int primary_offset = PrimaryOffset(name, flags, map);
64 Entry* primary = entry(primary_, primary_offset);
65 Code* old_code = primary->value;
66
67 // If the primary entry has useful data in it, we retire it to the
68 // secondary cache before overwriting it.
69 if (old_code != isolate_->builtins()->builtin(Builtins::kIllegal)) {
70 Map* old_map = primary->map;
71 Code::Flags old_flags =
72 Code::RemoveTypeAndHolderFromFlags(old_code->flags());
73 int seed = PrimaryOffset(primary->key, old_flags, old_map);
74 int secondary_offset = SecondaryOffset(primary->key, old_flags, seed);
75 Entry* secondary = entry(secondary_, secondary_offset);
76 *secondary = *primary;
77 }
78
79 // Update primary cache.
80 primary->key = name;
81 primary->value = code;
82 primary->map = map;
83 isolate()->counters()->megamorphic_stub_cache_updates()->Increment();
84 return code;
85 }
86
87
88 Code* StubCache::Get(Name* name, Map* map, Code::Flags flags) {
89 flags = CommonStubCacheChecks(name, map, flags);
90 int primary_offset = PrimaryOffset(name, flags, map);
91 Entry* primary = entry(primary_, primary_offset);
92 if (primary->key == name && primary->map == map) {
93 return primary->value;
94 }
95 int secondary_offset = SecondaryOffset(name, flags, primary_offset);
96 Entry* secondary = entry(secondary_, secondary_offset);
97 if (secondary->key == name && secondary->map == map) {
98 return secondary->value;
99 }
100 return NULL;
101 }
102
103 14
104 Handle<Code> PropertyICCompiler::Find(Handle<Name> name, 15 Handle<Code> PropertyICCompiler::Find(Handle<Name> name,
105 Handle<Map> stub_holder, Code::Kind kind, 16 Handle<Map> stub_holder, Code::Kind kind,
106 ExtraICState extra_state, 17 ExtraICState extra_state,
107 CacheHolderFlag cache_holder) { 18 CacheHolderFlag cache_holder) {
108 Code::Flags flags = Code::ComputeMonomorphicFlags( 19 Code::Flags flags =
109 kind, extra_state, cache_holder); 20 Code::ComputeMonomorphicFlags(kind, extra_state, cache_holder);
110 Object* probe = stub_holder->FindInCodeCache(*name, flags); 21 Object* probe = stub_holder->FindInCodeCache(*name, flags);
111 if (probe->IsCode()) return handle(Code::cast(probe)); 22 if (probe->IsCode()) return handle(Code::cast(probe));
112 return Handle<Code>::null(); 23 return Handle<Code>::null();
113 } 24 }
114 25
115 26
116 Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name, 27 Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name,
117 Handle<Map> stub_holder, 28 Handle<Map> stub_holder,
118 Code::Kind kind, 29 Code::Kind kind,
119 CacheHolderFlag cache_holder, 30 CacheHolderFlag cache_holder,
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 165
255 Handle<String> name = isolate->factory()->KeyedStoreMonomorphic_string(); 166 Handle<String> name = isolate->factory()->KeyedStoreMonomorphic_string();
256 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate); 167 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate);
257 if (probe->IsCode()) return Handle<Code>::cast(probe); 168 if (probe->IsCode()) return Handle<Code>::cast(probe);
258 169
259 PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state); 170 PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state);
260 Handle<Code> code = 171 Handle<Code> code =
261 compiler.CompileKeyedStoreMonomorphic(receiver_map, store_mode); 172 compiler.CompileKeyedStoreMonomorphic(receiver_map, store_mode);
262 173
263 Map::UpdateCodeCache(receiver_map, name, code); 174 Map::UpdateCodeCache(receiver_map, name, code);
264 DCHECK(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) 175 DCHECK(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) ==
265 == store_mode); 176 store_mode);
266 return code; 177 return code;
267 } 178 }
268 179
269 180
270 #define CALL_LOGGER_TAG(kind, type) (Logger::KEYED_##type) 181 #define CALL_LOGGER_TAG(kind, type) (Logger::KEYED_##type)
271 182
272 static void FillCache(Isolate* isolate, Handle<Code> code) {
273 Handle<UnseededNumberDictionary> dictionary =
274 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(),
275 code->flags(),
276 code);
277 isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
278 }
279
280 183
281 Code* PropertyICCompiler::FindPreMonomorphic(Isolate* isolate, Code::Kind kind, 184 Code* PropertyICCompiler::FindPreMonomorphic(Isolate* isolate, Code::Kind kind,
282 ExtraICState state) { 185 ExtraICState state) {
283 Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state); 186 Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state);
284 UnseededNumberDictionary* dictionary = 187 UnseededNumberDictionary* dictionary =
285 isolate->heap()->non_monomorphic_cache(); 188 isolate->heap()->non_monomorphic_cache();
286 int entry = dictionary->FindEntry(isolate, flags); 189 int entry = dictionary->FindEntry(isolate, flags);
287 DCHECK(entry != -1); 190 DCHECK(entry != -1);
288 Object* code = dictionary->ValueAt(entry); 191 Object* code = dictionary->ValueAt(entry);
289 // This might be called during the marking phase of the collector 192 // This might be called during the marking phase of the collector
290 // hence the unchecked cast. 193 // hence the unchecked cast.
291 return reinterpret_cast<Code*>(code); 194 return reinterpret_cast<Code*>(code);
292 } 195 }
293 196
294 197
198 static void FillCache(Isolate* isolate, Handle<Code> code) {
199 Handle<UnseededNumberDictionary> dictionary = UnseededNumberDictionary::Set(
200 isolate->factory()->non_monomorphic_cache(), code->flags(), code);
201 isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
202 }
203
204
295 Handle<Code> PropertyICCompiler::ComputeLoad(Isolate* isolate, 205 Handle<Code> PropertyICCompiler::ComputeLoad(Isolate* isolate,
296 InlineCacheState ic_state, 206 InlineCacheState ic_state,
297 ExtraICState extra_state) { 207 ExtraICState extra_state) {
298 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, ic_state, extra_state); 208 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, ic_state, extra_state);
299 Handle<UnseededNumberDictionary> cache = 209 Handle<UnseededNumberDictionary> cache =
300 isolate->factory()->non_monomorphic_cache(); 210 isolate->factory()->non_monomorphic_cache();
301 int entry = cache->FindEntry(isolate, flags); 211 int entry = cache->FindEntry(isolate, flags);
302 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 212 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
303 213
304 PropertyICCompiler compiler(isolate, Code::LOAD_IC); 214 PropertyICCompiler compiler(isolate, Code::LOAD_IC);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 Handle<Code> PropertyICCompiler::ComputeKeyedStorePolymorphic( 320 Handle<Code> PropertyICCompiler::ComputeKeyedStorePolymorphic(
411 MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode, 321 MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode,
412 StrictMode strict_mode) { 322 StrictMode strict_mode) {
413 Isolate* isolate = receiver_maps->at(0)->GetIsolate(); 323 Isolate* isolate = receiver_maps->at(0)->GetIsolate();
414 DCHECK(store_mode == STANDARD_STORE || 324 DCHECK(store_mode == STANDARD_STORE ||
415 store_mode == STORE_AND_GROW_NO_TRANSITION || 325 store_mode == STORE_AND_GROW_NO_TRANSITION ||
416 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 326 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
417 store_mode == STORE_NO_TRANSITION_HANDLE_COW); 327 store_mode == STORE_NO_TRANSITION_HANDLE_COW);
418 Handle<PolymorphicCodeCache> cache = 328 Handle<PolymorphicCodeCache> cache =
419 isolate->factory()->polymorphic_code_cache(); 329 isolate->factory()->polymorphic_code_cache();
420 ExtraICState extra_state = KeyedStoreIC::ComputeExtraICState( 330 ExtraICState extra_state =
421 strict_mode, store_mode); 331 KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode);
422 Code::Flags flags = 332 Code::Flags flags =
423 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state); 333 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state);
424 Handle<Object> probe = cache->Lookup(receiver_maps, flags); 334 Handle<Object> probe = cache->Lookup(receiver_maps, flags);
425 if (probe->IsCode()) return Handle<Code>::cast(probe); 335 if (probe->IsCode()) return Handle<Code>::cast(probe);
426 336
427 PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state); 337 PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state);
428 Handle<Code> code = 338 Handle<Code> code =
429 compiler.CompileKeyedStorePolymorphic(receiver_maps, store_mode); 339 compiler.CompileKeyedStorePolymorphic(receiver_maps, store_mode);
430 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 340 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
431 return code; 341 return code;
432 } 342 }
433 343
434 344
435 void StubCache::Clear() {
436 Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal);
437 for (int i = 0; i < kPrimaryTableSize; i++) {
438 primary_[i].key = isolate()->heap()->empty_string();
439 primary_[i].map = NULL;
440 primary_[i].value = empty;
441 }
442 for (int j = 0; j < kSecondaryTableSize; j++) {
443 secondary_[j].key = isolate()->heap()->empty_string();
444 secondary_[j].map = NULL;
445 secondary_[j].value = empty;
446 }
447 }
448
449
450 void StubCache::CollectMatchingMaps(SmallMapList* types,
451 Handle<Name> name,
452 Code::Flags flags,
453 Handle<Context> native_context,
454 Zone* zone) {
455 for (int i = 0; i < kPrimaryTableSize; i++) {
456 if (primary_[i].key == *name) {
457 Map* map = primary_[i].map;
458 // Map can be NULL, if the stub is constant function call
459 // with a primitive receiver.
460 if (map == NULL) continue;
461
462 int offset = PrimaryOffset(*name, flags, map);
463 if (entry(primary_, offset) == &primary_[i] &&
464 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
465 types->AddMapIfMissing(Handle<Map>(map), zone);
466 }
467 }
468 }
469
470 for (int i = 0; i < kSecondaryTableSize; i++) {
471 if (secondary_[i].key == *name) {
472 Map* map = secondary_[i].map;
473 // Map can be NULL, if the stub is constant function call
474 // with a primitive receiver.
475 if (map == NULL) continue;
476
477 // Lookup in primary table and skip duplicates.
478 int primary_offset = PrimaryOffset(*name, flags, map);
479
480 // Lookup in secondary table and add matches.
481 int offset = SecondaryOffset(*name, flags, primary_offset);
482 if (entry(secondary_, offset) == &secondary_[i] &&
483 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
484 types->AddMapIfMissing(Handle<Map>(map), zone);
485 }
486 }
487 }
488 }
489
490
491 // ------------------------------------------------------------------------
492 // StubCompiler implementation.
493
494
495 RUNTIME_FUNCTION(StoreCallbackProperty) {
496 Handle<JSObject> receiver = args.at<JSObject>(0);
497 Handle<JSObject> holder = args.at<JSObject>(1);
498 Handle<ExecutableAccessorInfo> callback = args.at<ExecutableAccessorInfo>(2);
499 Handle<Name> name = args.at<Name>(3);
500 Handle<Object> value = args.at<Object>(4);
501 HandleScope scope(isolate);
502
503 DCHECK(callback->IsCompatibleReceiver(*receiver));
504
505 Address setter_address = v8::ToCData<Address>(callback->setter());
506 v8::AccessorNameSetterCallback fun =
507 FUNCTION_CAST<v8::AccessorNameSetterCallback>(setter_address);
508 DCHECK(fun != NULL);
509
510 LOG(isolate, ApiNamedPropertyAccess("store", *receiver, *name));
511 PropertyCallbackArguments custom_args(isolate, callback->data(), *receiver,
512 *holder);
513 custom_args.Call(fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value));
514 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
515 return *value;
516 }
517
518
519 /**
520 * Attempts to load a property with an interceptor (which must be present),
521 * but doesn't search the prototype chain.
522 *
523 * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't
524 * provide any value for the given name.
525 */
526 RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly) {
527 DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength);
528 Handle<Name> name_handle =
529 args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex);
530 Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(
531 NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex);
532
533 // TODO(rossberg): Support symbols in the API.
534 if (name_handle->IsSymbol())
535 return isolate->heap()->no_interceptor_result_sentinel();
536 Handle<String> name = Handle<String>::cast(name_handle);
537
538 Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
539 v8::NamedPropertyGetterCallback getter =
540 FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address);
541 DCHECK(getter != NULL);
542
543 Handle<JSObject> receiver =
544 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
545 Handle<JSObject> holder =
546 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex);
547 PropertyCallbackArguments callback_args(
548 isolate, interceptor_info->data(), *receiver, *holder);
549 {
550 // Use the interceptor getter.
551 HandleScope scope(isolate);
552 v8::Handle<v8::Value> r =
553 callback_args.Call(getter, v8::Utils::ToLocal(name));
554 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
555 if (!r.IsEmpty()) {
556 Handle<Object> result = v8::Utils::OpenHandle(*r);
557 result->VerifyApiCallResultType();
558 return *v8::Utils::OpenHandle(*r);
559 }
560 }
561
562 return isolate->heap()->no_interceptor_result_sentinel();
563 }
564
565
566 static Object* ThrowReferenceError(Isolate* isolate, Name* name) {
567 // If the load is non-contextual, just return the undefined result.
568 // Note that both keyed and non-keyed loads may end up here.
569 HandleScope scope(isolate);
570 LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
571 if (ic.contextual_mode() != CONTEXTUAL) {
572 return isolate->heap()->undefined_value();
573 }
574
575 // Throw a reference error.
576 Handle<Name> name_handle(name);
577 Handle<Object> error =
578 isolate->factory()->NewReferenceError("not_defined",
579 HandleVector(&name_handle, 1));
580 return isolate->Throw(*error);
581 }
582
583
584 /**
585 * Loads a property with an interceptor performing post interceptor
586 * lookup if interceptor failed.
587 */
588 RUNTIME_FUNCTION(LoadPropertyWithInterceptor) {
589 HandleScope scope(isolate);
590 DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength);
591 Handle<Name> name =
592 args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex);
593 Handle<JSObject> receiver =
594 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
595 Handle<JSObject> holder =
596 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex);
597
598 Handle<Object> result;
599 LookupIterator it(receiver, name, holder);
600 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
601 isolate, result, JSObject::GetProperty(&it));
602
603 if (it.IsFound()) return *result;
604
605 return ThrowReferenceError(isolate, Name::cast(args[0]));
606 }
607
608
609 RUNTIME_FUNCTION(StorePropertyWithInterceptor) {
610 HandleScope scope(isolate);
611 DCHECK(args.length() == 3);
612 StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
613 Handle<JSObject> receiver = args.at<JSObject>(0);
614 Handle<Name> name = args.at<Name>(1);
615 Handle<Object> value = args.at<Object>(2);
616 #ifdef DEBUG
617 PrototypeIterator iter(isolate, receiver,
618 PrototypeIterator::START_AT_RECEIVER);
619 bool found = false;
620 while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
621 Handle<Object> current = PrototypeIterator::GetCurrent(iter);
622 if (current->IsJSObject() &&
623 Handle<JSObject>::cast(current)->HasNamedInterceptor()) {
624 found = true;
625 break;
626 }
627 }
628 DCHECK(found);
629 #endif
630 Handle<Object> result;
631 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
632 isolate, result,
633 JSObject::SetProperty(receiver, name, value, ic.strict_mode()));
634 return *result;
635 }
636
637
638 RUNTIME_FUNCTION(LoadElementWithInterceptor) {
639 HandleScope scope(isolate);
640 Handle<JSObject> receiver = args.at<JSObject>(0);
641 DCHECK(args.smi_at(1) >= 0);
642 uint32_t index = args.smi_at(1);
643 Handle<Object> result;
644 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
645 isolate, result,
646 JSObject::GetElementWithInterceptor(receiver, receiver, index));
647 return *result;
648 }
649
650
651 Handle<Code> PropertyICCompiler::CompileLoadInitialize(Code::Flags flags) { 345 Handle<Code> PropertyICCompiler::CompileLoadInitialize(Code::Flags flags) {
652 LoadIC::GenerateInitialize(masm()); 346 LoadIC::GenerateInitialize(masm());
653 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadInitialize"); 347 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadInitialize");
654 PROFILE(isolate(), 348 PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_INITIALIZE_TAG, *code, 0));
655 CodeCreateEvent(Logger::LOAD_INITIALIZE_TAG, *code, 0));
656 return code; 349 return code;
657 } 350 }
658 351
659 352
660 Handle<Code> PropertyICCompiler::CompileLoadPreMonomorphic(Code::Flags flags) { 353 Handle<Code> PropertyICCompiler::CompileLoadPreMonomorphic(Code::Flags flags) {
661 LoadIC::GeneratePreMonomorphic(masm()); 354 LoadIC::GeneratePreMonomorphic(masm());
662 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadPreMonomorphic"); 355 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadPreMonomorphic");
663 PROFILE(isolate(), 356 PROFILE(isolate(),
664 CodeCreateEvent(Logger::LOAD_PREMONOMORPHIC_TAG, *code, 0)); 357 CodeCreateEvent(Logger::LOAD_PREMONOMORPHIC_TAG, *code, 0));
665 return code; 358 return code;
666 } 359 }
667 360
668 361
669 Handle<Code> PropertyICCompiler::CompileLoadMegamorphic(Code::Flags flags) { 362 Handle<Code> PropertyICCompiler::CompileLoadMegamorphic(Code::Flags flags) {
670 LoadIC::GenerateMegamorphic(masm()); 363 LoadIC::GenerateMegamorphic(masm());
671 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadMegamorphic"); 364 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadMegamorphic");
672 PROFILE(isolate(), 365 PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0));
673 CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0));
674 return code; 366 return code;
675 } 367 }
676 368
677 369
678 Handle<Code> PropertyICCompiler::CompileStoreInitialize(Code::Flags flags) { 370 Handle<Code> PropertyICCompiler::CompileStoreInitialize(Code::Flags flags) {
679 StoreIC::GenerateInitialize(masm()); 371 StoreIC::GenerateInitialize(masm());
680 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreInitialize"); 372 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreInitialize");
681 PROFILE(isolate(), 373 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_INITIALIZE_TAG, *code, 0));
682 CodeCreateEvent(Logger::STORE_INITIALIZE_TAG, *code, 0));
683 return code; 374 return code;
684 } 375 }
685 376
686 377
687 Handle<Code> PropertyICCompiler::CompileStorePreMonomorphic(Code::Flags flags) { 378 Handle<Code> PropertyICCompiler::CompileStorePreMonomorphic(Code::Flags flags) {
688 StoreIC::GeneratePreMonomorphic(masm()); 379 StoreIC::GeneratePreMonomorphic(masm());
689 Handle<Code> code = GetCodeWithFlags(flags, "CompileStorePreMonomorphic"); 380 Handle<Code> code = GetCodeWithFlags(flags, "CompileStorePreMonomorphic");
690 PROFILE(isolate(), 381 PROFILE(isolate(),
691 CodeCreateEvent(Logger::STORE_PREMONOMORPHIC_TAG, *code, 0)); 382 CodeCreateEvent(Logger::STORE_PREMONOMORPHIC_TAG, *code, 0));
692 return code; 383 return code;
693 } 384 }
694 385
695 386
696 Handle<Code> PropertyICCompiler::CompileStoreGeneric(Code::Flags flags) { 387 Handle<Code> PropertyICCompiler::CompileStoreGeneric(Code::Flags flags) {
697 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); 388 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
698 StrictMode strict_mode = StoreIC::GetStrictMode(extra_state); 389 StrictMode strict_mode = StoreIC::GetStrictMode(extra_state);
699 StoreIC::GenerateRuntimeSetProperty(masm(), strict_mode); 390 StoreIC::GenerateRuntimeSetProperty(masm(), strict_mode);
700 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreGeneric"); 391 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreGeneric");
701 PROFILE(isolate(), 392 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_GENERIC_TAG, *code, 0));
702 CodeCreateEvent(Logger::STORE_GENERIC_TAG, *code, 0));
703 return code; 393 return code;
704 } 394 }
705 395
706 396
707 Handle<Code> PropertyICCompiler::CompileStoreMegamorphic(Code::Flags flags) { 397 Handle<Code> PropertyICCompiler::CompileStoreMegamorphic(Code::Flags flags) {
708 StoreIC::GenerateMegamorphic(masm()); 398 StoreIC::GenerateMegamorphic(masm());
709 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic"); 399 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic");
710 PROFILE(isolate(), 400 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0));
711 CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0));
712 return code; 401 return code;
713 } 402 }
714 403
715 404
716 #undef CALL_LOGGER_TAG 405 #undef CALL_LOGGER_TAG
717 406
718 407
719 Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags, 408 Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
720 const char* name) { 409 const char* name) {
721 // Create code object in the heap. 410 // Create code object in the heap.
722 CodeDesc desc; 411 CodeDesc desc;
723 masm()->GetCode(&desc); 412 masm()->GetCode(&desc);
724 Handle<Code> code = factory()->NewCode(desc, flags, masm()->CodeObject()); 413 Handle<Code> code = factory()->NewCode(desc, flags, masm()->CodeObject());
725 if (code->IsCodeStubOrIC()) code->set_stub_key(CodeStub::NoCacheKey()); 414 if (code->IsCodeStubOrIC()) code->set_stub_key(CodeStub::NoCacheKey());
726 #ifdef ENABLE_DISASSEMBLER 415 #ifdef ENABLE_DISASSEMBLER
727 if (FLAG_print_code_stubs) { 416 if (FLAG_print_code_stubs) {
728 OFStream os(stdout); 417 OFStream os(stdout);
729 code->Disassemble(name, os); 418 code->Disassemble(name, os);
730 } 419 }
731 #endif 420 #endif
732 return code; 421 return code;
733 } 422 }
734 423
735 424
736 Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags, 425 Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
737 Handle<Name> name) { 426 Handle<Name> name) {
738 return (FLAG_print_code_stubs && !name.is_null() && name->IsString()) 427 return (FLAG_print_code_stubs && !name.is_null() && name->IsString())
739 ? GetCodeWithFlags(flags, Handle<String>::cast(name)->ToCString().get()) 428 ? GetCodeWithFlags(flags,
740 : GetCodeWithFlags(flags, NULL); 429 Handle<String>::cast(name)->ToCString().get())
430 : GetCodeWithFlags(flags, NULL);
741 } 431 }
742 432
743 433
744 #define __ ACCESS_MASM(masm()) 434 #define __ ACCESS_MASM(masm())
745 435
746 436
747 Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg, 437 Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
748 Handle<Name> name, 438 Handle<Name> name,
749 Label* miss) { 439 Label* miss) {
750 PrototypeCheckType check_type = CHECK_ALL_MAPS; 440 PrototypeCheckType check_type = CHECK_ALL_MAPS;
751 int function_index = -1; 441 int function_index = -1;
752 if (type()->Is(HeapType::String())) { 442 if (type()->Is(HeapType::String())) {
753 function_index = Context::STRING_FUNCTION_INDEX; 443 function_index = Context::STRING_FUNCTION_INDEX;
754 } else if (type()->Is(HeapType::Symbol())) { 444 } else if (type()->Is(HeapType::Symbol())) {
755 function_index = Context::SYMBOL_FUNCTION_INDEX; 445 function_index = Context::SYMBOL_FUNCTION_INDEX;
756 } else if (type()->Is(HeapType::Number())) { 446 } else if (type()->Is(HeapType::Number())) {
757 function_index = Context::NUMBER_FUNCTION_INDEX; 447 function_index = Context::NUMBER_FUNCTION_INDEX;
758 } else if (type()->Is(HeapType::Boolean())) { 448 } else if (type()->Is(HeapType::Boolean())) {
759 function_index = Context::BOOLEAN_FUNCTION_INDEX; 449 function_index = Context::BOOLEAN_FUNCTION_INDEX;
760 } else { 450 } else {
761 check_type = SKIP_RECEIVER; 451 check_type = SKIP_RECEIVER;
762 } 452 }
763 453
764 if (check_type == CHECK_ALL_MAPS) { 454 if (check_type == CHECK_ALL_MAPS) {
765 GenerateDirectLoadGlobalFunctionPrototype( 455 GenerateDirectLoadGlobalFunctionPrototype(masm(), function_index,
766 masm(), function_index, scratch1(), miss); 456 scratch1(), miss);
767 Object* function = isolate()->native_context()->get(function_index); 457 Object* function = isolate()->native_context()->get(function_index);
768 Object* prototype = JSFunction::cast(function)->instance_prototype(); 458 Object* prototype = JSFunction::cast(function)->instance_prototype();
769 set_type_for_object(handle(prototype, isolate())); 459 set_type_for_object(handle(prototype, isolate()));
770 object_reg = scratch1(); 460 object_reg = scratch1();
771 } 461 }
772 462
773 // Check that the maps starting from the prototype haven't changed. 463 // Check that the maps starting from the prototype haven't changed.
774 return CheckPrototypes(object_reg, scratch1(), scratch2(), scratch3(), name, 464 return CheckPrototypes(object_reg, scratch1(), scratch2(), scratch3(), name,
775 miss, check_type); 465 miss, check_type);
776 } 466 }
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 GenerateLoadCallback(reg, callback); 568 GenerateLoadCallback(reg, callback);
879 return GetCode(kind(), Code::FAST, name); 569 return GetCode(kind(), Code::FAST, name);
880 } 570 }
881 571
882 572
883 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( 573 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
884 Handle<Name> name, const CallOptimization& call_optimization) { 574 Handle<Name> name, const CallOptimization& call_optimization) {
885 DCHECK(call_optimization.is_simple_api_call()); 575 DCHECK(call_optimization.is_simple_api_call());
886 Frontend(receiver(), name); 576 Frontend(receiver(), name);
887 Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate()); 577 Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate());
888 GenerateFastApiCall( 578 GenerateFastApiCall(masm(), call_optimization, receiver_map, receiver(),
889 masm(), call_optimization, receiver_map, 579 scratch1(), false, 0, NULL);
890 receiver(), scratch1(), false, 0, NULL);
891 return GetCode(kind(), Code::FAST, name); 580 return GetCode(kind(), Code::FAST, name);
892 } 581 }
893 582
894 583
895 Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor( 584 Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor(
896 LookupIterator* it) { 585 LookupIterator* it) {
897 // So far the most popular follow ups for interceptor loads are FIELD and 586 // So far the most popular follow ups for interceptor loads are FIELD and
898 // ExecutableAccessorInfo, so inline only them. Other cases may be added 587 // ExecutableAccessorInfo, so inline only them. Other cases may be added
899 // later. 588 // later.
900 bool inline_followup = it->state() == LookupIterator::PROPERTY; 589 bool inline_followup = it->state() == LookupIterator::PROPERTY;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 GenerateStoreViaSetter(masm(), type(), receiver(), setter); 715 GenerateStoreViaSetter(masm(), type(), receiver(), setter);
1027 716
1028 return GetCode(kind(), Code::FAST, name); 717 return GetCode(kind(), Code::FAST, name);
1029 } 718 }
1030 719
1031 720
1032 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 721 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
1033 Handle<JSObject> object, Handle<Name> name, 722 Handle<JSObject> object, Handle<Name> name,
1034 const CallOptimization& call_optimization) { 723 const CallOptimization& call_optimization) {
1035 Frontend(receiver(), name); 724 Frontend(receiver(), name);
1036 Register values[] = { value() }; 725 Register values[] = {value()};
1037 GenerateFastApiCall( 726 GenerateFastApiCall(masm(), call_optimization, handle(object->map()),
1038 masm(), call_optimization, handle(object->map()), 727 receiver(), scratch1(), true, 1, values);
1039 receiver(), scratch1(), true, 1, values);
1040 return GetCode(kind(), Code::FAST, name); 728 return GetCode(kind(), Code::FAST, name);
1041 } 729 }
1042 730
1043 731
1044 Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic( 732 Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic(
1045 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) { 733 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
1046 ElementsKind elements_kind = receiver_map->elements_kind(); 734 ElementsKind elements_kind = receiver_map->elements_kind();
1047 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; 735 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
1048 Handle<Code> stub; 736 Handle<Code> stub;
1049 if (receiver_map->has_fast_elements() || 737 if (receiver_map->has_fast_elements() ||
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 KeyedStoreIC::GenerateSlow(masm); 879 KeyedStoreIC::GenerateSlow(masm);
1192 } 880 }
1193 881
1194 882
1195 CallOptimization::CallOptimization(Handle<JSFunction> function) { 883 CallOptimization::CallOptimization(Handle<JSFunction> function) {
1196 Initialize(function); 884 Initialize(function);
1197 } 885 }
1198 886
1199 887
1200 Handle<JSObject> CallOptimization::LookupHolderOfExpectedType( 888 Handle<JSObject> CallOptimization::LookupHolderOfExpectedType(
1201 Handle<Map> object_map, 889 Handle<Map> object_map, HolderLookup* holder_lookup) const {
1202 HolderLookup* holder_lookup) const {
1203 DCHECK(is_simple_api_call()); 890 DCHECK(is_simple_api_call());
1204 if (!object_map->IsJSObjectMap()) { 891 if (!object_map->IsJSObjectMap()) {
1205 *holder_lookup = kHolderNotFound; 892 *holder_lookup = kHolderNotFound;
1206 return Handle<JSObject>::null(); 893 return Handle<JSObject>::null();
1207 } 894 }
1208 if (expected_receiver_type_.is_null() || 895 if (expected_receiver_type_.is_null() ||
1209 expected_receiver_type_->IsTemplateFor(*object_map)) { 896 expected_receiver_type_->IsTemplateFor(*object_map)) {
1210 *holder_lookup = kHolderIsReceiver; 897 *holder_lookup = kHolderIsReceiver;
1211 return Handle<JSObject>::null(); 898 return Handle<JSObject>::null();
1212 } 899 }
(...skipping 11 matching lines...) Expand all
1224 return Handle<JSObject>::null(); 911 return Handle<JSObject>::null();
1225 } 912 }
1226 913
1227 914
1228 bool CallOptimization::IsCompatibleReceiver(Handle<Object> receiver, 915 bool CallOptimization::IsCompatibleReceiver(Handle<Object> receiver,
1229 Handle<JSObject> holder) const { 916 Handle<JSObject> holder) const {
1230 DCHECK(is_simple_api_call()); 917 DCHECK(is_simple_api_call());
1231 if (!receiver->IsJSObject()) return false; 918 if (!receiver->IsJSObject()) return false;
1232 Handle<Map> map(JSObject::cast(*receiver)->map()); 919 Handle<Map> map(JSObject::cast(*receiver)->map());
1233 HolderLookup holder_lookup; 920 HolderLookup holder_lookup;
1234 Handle<JSObject> api_holder = 921 Handle<JSObject> api_holder = LookupHolderOfExpectedType(map, &holder_lookup);
1235 LookupHolderOfExpectedType(map, &holder_lookup);
1236 switch (holder_lookup) { 922 switch (holder_lookup) {
1237 case kHolderNotFound: 923 case kHolderNotFound:
1238 return false; 924 return false;
1239 case kHolderIsReceiver: 925 case kHolderIsReceiver:
1240 return true; 926 return true;
1241 case kHolderFound: 927 case kHolderFound:
1242 if (api_holder.is_identical_to(holder)) return true; 928 if (api_holder.is_identical_to(holder)) return true;
1243 // Check if holder is in prototype chain of api_holder. 929 // Check if holder is in prototype chain of api_holder.
1244 { 930 {
1245 JSObject* object = *api_holder; 931 JSObject* object = *api_holder;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 api_call_info_ = 965 api_call_info_ =
1280 Handle<CallHandlerInfo>(CallHandlerInfo::cast(info->call_code())); 966 Handle<CallHandlerInfo>(CallHandlerInfo::cast(info->call_code()));
1281 967
1282 // Accept signatures that either have no restrictions at all or 968 // Accept signatures that either have no restrictions at all or
1283 // only have restrictions on the receiver. 969 // only have restrictions on the receiver.
1284 if (!info->signature()->IsUndefined()) { 970 if (!info->signature()->IsUndefined()) {
1285 Handle<SignatureInfo> signature = 971 Handle<SignatureInfo> signature =
1286 Handle<SignatureInfo>(SignatureInfo::cast(info->signature())); 972 Handle<SignatureInfo>(SignatureInfo::cast(info->signature()));
1287 if (!signature->args()->IsUndefined()) return; 973 if (!signature->args()->IsUndefined()) return;
1288 if (!signature->receiver()->IsUndefined()) { 974 if (!signature->receiver()->IsUndefined()) {
1289 expected_receiver_type_ = 975 expected_receiver_type_ = Handle<FunctionTemplateInfo>(
1290 Handle<FunctionTemplateInfo>( 976 FunctionTemplateInfo::cast(signature->receiver()));
1291 FunctionTemplateInfo::cast(signature->receiver()));
1292 } 977 }
1293 } 978 }
1294 979
1295 is_simple_api_call_ = true; 980 is_simple_api_call_ = true;
1296 } 981 }
1297 982 }
1298 983 } // namespace v8::internal
1299 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic/ic-compiler.h ('k') | src/ic/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698