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

Side by Side Diff: src/ic.cc

Issue 170563002: Load target types and handlers before IC computation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 10 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.h ('k') | no next file » | 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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 StackFrameIterator it(isolate); 142 StackFrameIterator it(isolate);
143 for (int i = 0; i < depth + 1; i++) it.Advance(); 143 for (int i = 0; i < depth + 1; i++) it.Advance();
144 StackFrame* frame = it.frame(); 144 StackFrame* frame = it.frame();
145 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); 145 ASSERT(fp == frame->fp() && pc_address == frame->pc_address());
146 #endif 146 #endif
147 fp_ = fp; 147 fp_ = fp;
148 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); 148 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address);
149 target_ = handle(raw_target(), isolate); 149 target_ = handle(raw_target(), isolate);
150 state_ = target_->ic_state(); 150 state_ = target_->ic_state();
151 extra_ic_state_ = target_->extra_ic_state(); 151 extra_ic_state_ = target_->extra_ic_state();
152 target()->FindAllTypes(&types_);
153 target()->FindHandlers(&handlers_);
152 } 154 }
153 155
154 156
155 #ifdef ENABLE_DEBUGGER_SUPPORT 157 #ifdef ENABLE_DEBUGGER_SUPPORT
156 Address IC::OriginalCodeAddress() const { 158 Address IC::OriginalCodeAddress() const {
157 HandleScope scope(isolate()); 159 HandleScope scope(isolate());
158 // Compute the JavaScript frame for the frame pointer of this IC 160 // Compute the JavaScript frame for the frame pointer of this IC
159 // structure. We need this to be able to find the function 161 // structure. We need this to be able to find the function
160 // corresponding to the frame. 162 // corresponding to the frame.
161 StackFrameIterator it(isolate()); 163 StackFrameIterator it(isolate());
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 276
275 // The stub is not in the cache. We've ruled out all other kinds of failure 277 // The stub is not in the cache. We've ruled out all other kinds of failure
276 // except for proptotype chain changes, a deprecated map, a map that's 278 // except for proptotype chain changes, a deprecated map, a map that's
277 // different from the one that the stub expects, elements kind changes, or a 279 // different from the one that the stub expects, elements kind changes, or a
278 // constant global property that will become mutable. Threat all those 280 // constant global property that will become mutable. Threat all those
279 // situations as prototype failures (stay monomorphic if possible). 281 // situations as prototype failures (stay monomorphic if possible).
280 282
281 // If the IC is shared between multiple receivers (slow dictionary mode), then 283 // If the IC is shared between multiple receivers (slow dictionary mode), then
282 // the map cannot be deprecated and the stub invalidated. 284 // the map cannot be deprecated and the stub invalidated.
283 if (cache_holder == OWN_MAP) { 285 if (cache_holder == OWN_MAP) {
284 Map* old_map = target()->FindFirstMap(); 286 Map* old_map = first_map();
285 if (old_map == *map) return true; 287 if (old_map == *map) return true;
286 if (old_map != NULL) { 288 if (old_map != NULL) {
287 if (old_map->is_deprecated()) return true; 289 if (old_map->is_deprecated()) return true;
288 if (IsMoreGeneralElementsKindTransition(old_map->elements_kind(), 290 if (IsMoreGeneralElementsKindTransition(old_map->elements_kind(),
289 map->elements_kind())) { 291 map->elements_kind())) {
290 return true; 292 return true;
291 } 293 }
292 } 294 }
293 } 295 }
294 296
295 if (receiver->IsGlobalObject()) { 297 if (receiver->IsGlobalObject()) {
296 LookupResult lookup(isolate()); 298 LookupResult lookup(isolate());
297 GlobalObject* global = GlobalObject::cast(*receiver); 299 GlobalObject* global = GlobalObject::cast(*receiver);
298 global->LocalLookupRealNamedProperty(*name, &lookup); 300 global->LocalLookupRealNamedProperty(*name, &lookup);
299 if (!lookup.IsFound()) return false; 301 if (!lookup.IsFound()) return false;
300 PropertyCell* cell = global->GetPropertyCell(&lookup); 302 PropertyCell* cell = global->GetPropertyCell(&lookup);
301 return cell->type()->IsConstant(); 303 return cell->type()->IsConstant();
302 } 304 }
303 305
304 return false; 306 return false;
305 } 307 }
306 308
307 309
308 void IC::TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name) { 310 void IC::TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name) {
309 CodeHandleList handlers; 311 for (int i = 0; i < handlers()->length(); i++) {
310 target()->FindHandlers(&handlers); 312 Handle<Code> handler = handlers()->at(i);
311 for (int i = 0; i < handlers.length(); i++) {
312 Handle<Code> handler = handlers.at(i);
313 int index = map->IndexInCodeCache(*name, *handler); 313 int index = map->IndexInCodeCache(*name, *handler);
314 if (index >= 0) { 314 if (index >= 0) {
315 map->RemoveFromCodeCache(*name, *handler, index); 315 map->RemoveFromCodeCache(*name, *handler, index);
316 return; 316 return;
317 } 317 }
318 } 318 }
319 } 319 }
320 320
321 321
322 void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) { 322 void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) {
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 } 598 }
599 receiver_maps->Add(new_receiver_map); 599 receiver_maps->Add(new_receiver_map);
600 return true; 600 return true;
601 } 601 }
602 602
603 603
604 bool IC::UpdatePolymorphicIC(Handle<HeapType> type, 604 bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
605 Handle<String> name, 605 Handle<String> name,
606 Handle<Code> code) { 606 Handle<Code> code) {
607 if (!code->is_handler()) return false; 607 if (!code->is_handler()) return false;
608 TypeHandleList types;
609 CodeHandleList handlers;
610
611 int number_of_valid_types; 608 int number_of_valid_types;
612 int handler_to_overwrite = -1; 609 int handler_to_overwrite = -1;
613 610
614 target()->FindAllTypes(&types); 611 int number_of_types = types()->length();
615 int number_of_types = types.length();
616 number_of_valid_types = number_of_types; 612 number_of_valid_types = number_of_types;
617 613
618 for (int i = 0; i < number_of_types; i++) { 614 for (int i = 0; i < number_of_types; i++) {
619 Handle<HeapType> current_type = types.at(i); 615 Handle<HeapType> current_type = types()->at(i);
620 // Filter out deprecated maps to ensure their instances get migrated. 616 // Filter out deprecated maps to ensure their instances get migrated.
621 if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) { 617 if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) {
622 number_of_valid_types--; 618 number_of_valid_types--;
623 // If the receiver type is already in the polymorphic IC, this indicates 619 // If the receiver type is already in the polymorphic IC, this indicates
624 // there was a prototoype chain failure. In that case, just overwrite the 620 // there was a prototoype chain failure. In that case, just overwrite the
625 // handler. 621 // handler.
626 } else if (type->IsCurrently(current_type)) { 622 } else if (type->IsCurrently(current_type)) {
627 ASSERT(handler_to_overwrite == -1); 623 ASSERT(handler_to_overwrite == -1);
628 number_of_valid_types--; 624 number_of_valid_types--;
629 handler_to_overwrite = i; 625 handler_to_overwrite = i;
630 } 626 }
631 } 627 }
632 628
633 if (number_of_valid_types >= 4) return false; 629 if (number_of_valid_types >= 4) return false;
634 if (number_of_types == 0) return false; 630 if (number_of_types == 0) return false;
635 if (!target()->FindHandlers(&handlers, types.length())) return false; 631 if (handlers()->length() < types()->length()) return false;
636 632
637 number_of_valid_types++; 633 number_of_valid_types++;
638 if (handler_to_overwrite >= 0) { 634 if (handler_to_overwrite >= 0) {
639 handlers.Set(handler_to_overwrite, code); 635 handlers()->Set(handler_to_overwrite, code);
ulan 2014/02/18 14:50:26 This function modifies handlers and types. Do you
Toon Verwaest 2014/02/18 15:06:36 This is done at the end of IC computation. It shou
640 } else { 636 } else {
641 types.Add(type); 637 types()->Add(type);
642 handlers.Add(code); 638 handlers()->Add(code);
643 } 639 }
644 640
645 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( 641 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC(
646 kind(), &types, &handlers, number_of_valid_types, name, extra_ic_state()); 642 kind(), types(), handlers(), number_of_valid_types,
643 name, extra_ic_state());
647 set_target(*ic); 644 set_target(*ic);
648 return true; 645 return true;
649 } 646 }
650 647
651 648
652 Handle<HeapType> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { 649 Handle<HeapType> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) {
653 return object->IsJSGlobalObject() 650 return object->IsJSGlobalObject()
654 ? HeapType::Constant(Handle<JSGlobalObject>::cast(object), isolate) 651 ? HeapType::Constant(Handle<JSGlobalObject>::cast(object), isolate)
655 : HeapType::OfCurrently(object, isolate); 652 : HeapType::OfCurrently(object, isolate);
656 } 653 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 Handle<Code> handler, 691 Handle<Code> handler,
695 Handle<String> name) { 692 Handle<String> name) {
696 if (!handler->is_handler()) return set_target(*handler); 693 if (!handler->is_handler()) return set_target(*handler);
697 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( 694 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC(
698 kind(), name, type, handler, extra_ic_state()); 695 kind(), name, type, handler, extra_ic_state());
699 set_target(*ic); 696 set_target(*ic);
700 } 697 }
701 698
702 699
703 void IC::CopyICToMegamorphicCache(Handle<String> name) { 700 void IC::CopyICToMegamorphicCache(Handle<String> name) {
704 TypeHandleList types; 701 if (handlers()->length() < types()->length()) return;
705 CodeHandleList handlers; 702 for (int i = 0; i < types()->length(); i++) {
706 target()->FindAllTypes(&types); 703 UpdateMegamorphicCache(*types()->at(i), *name, *handlers()->at(i));
707 if (!target()->FindHandlers(&handlers, types.length())) return;
708 for (int i = 0; i < types.length(); i++) {
709 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i));
710 } 704 }
711 } 705 }
712 706
713 707
714 bool IC::IsTransitionOfMonomorphicTarget(Handle<HeapType> type) { 708 bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) {
715 if (!type->IsClass()) return false; 709 if (source_map == NULL) return true;
716 Map* receiver_map = *type->AsClass(); 710 if (target_map == NULL) return false;
717 Map* current_map = target()->FindFirstMap(); 711 ElementsKind target_elements_kind = target_map->elements_kind();
718 ElementsKind receiver_elements_kind = receiver_map->elements_kind(); 712 bool more_general_transition = IsMoreGeneralElementsKindTransition(
719 bool more_general_transition = 713 source_map->elements_kind(), target_elements_kind);
720 IsMoreGeneralElementsKindTransition(
721 current_map->elements_kind(), receiver_elements_kind);
722 Map* transitioned_map = more_general_transition 714 Map* transitioned_map = more_general_transition
723 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) 715 ? source_map->LookupElementsTransitionMap(target_elements_kind)
724 : NULL; 716 : NULL;
725 717 return transitioned_map == target_map;
726 return transitioned_map == receiver_map;
727 } 718 }
728 719
729 720
730 void IC::PatchCache(Handle<HeapType> type, 721 void IC::PatchCache(Handle<HeapType> type,
731 Handle<String> name, 722 Handle<String> name,
732 Handle<Code> code) { 723 Handle<Code> code) {
733 switch (state()) { 724 switch (state()) {
734 case UNINITIALIZED: 725 case UNINITIALIZED:
735 case PREMONOMORPHIC: 726 case PREMONOMORPHIC:
736 case MONOMORPHIC_PROTOTYPE_FAILURE: 727 case MONOMORPHIC_PROTOTYPE_FAILURE:
737 UpdateMonomorphicIC(type, code, name); 728 UpdateMonomorphicIC(type, code, name);
738 break; 729 break;
739 case MONOMORPHIC: { 730 case MONOMORPHIC: {
740 // For now, call stubs are allowed to rewrite to the same stub. This 731 // For now, call stubs are allowed to rewrite to the same stub. This
741 // happens e.g., when the field does not contain a function. 732 // happens e.g., when the field does not contain a function.
742 ASSERT(!target().is_identical_to(code)); 733 ASSERT(!target().is_identical_to(code));
743 Code* old_handler = target()->FindFirstHandler(); 734 Map* old_map = first_map();
744 if (old_handler == *code && IsTransitionOfMonomorphicTarget(type)) { 735 Code* old_handler = first_handler();
736 Map* map = type->IsClass() ? *type->AsClass() : NULL;
737 if (old_handler == *code &&
738 IsTransitionOfMonomorphicTarget(old_map, map)) {
745 UpdateMonomorphicIC(type, code, name); 739 UpdateMonomorphicIC(type, code, name);
746 break; 740 break;
747 } 741 }
748 // Fall through. 742 // Fall through.
749 } 743 }
750 case POLYMORPHIC: 744 case POLYMORPHIC:
751 if (!target()->is_keyed_stub()) { 745 if (!target()->is_keyed_stub()) {
752 if (UpdatePolymorphicIC(type, name, code)) break; 746 if (UpdatePolymorphicIC(type, name, code)) break;
753 CopyICToMegamorphicCache(name); 747 CopyICToMegamorphicCache(name);
754 } 748 }
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 MapHandleList target_receiver_maps; 997 MapHandleList target_receiver_maps;
1004 if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) { 998 if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) {
1005 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state 999 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
1006 // yet will do so and stay there. 1000 // yet will do so and stay there.
1007 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); 1001 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
1008 } 1002 }
1009 1003
1010 if (target().is_identical_to(string_stub())) { 1004 if (target().is_identical_to(string_stub())) {
1011 target_receiver_maps.Add(isolate()->factory()->string_map()); 1005 target_receiver_maps.Add(isolate()->factory()->string_map());
1012 } else { 1006 } else {
1013 target()->FindAllMaps(&target_receiver_maps); 1007 GetMapsFromTypes(&target_receiver_maps);
1014 if (target_receiver_maps.length() == 0) { 1008 if (target_receiver_maps.length() == 0) {
1015 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); 1009 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
1016 } 1010 }
1017 } 1011 }
1018 1012
1019 // The first time a receiver is seen that is a transitioned version of the 1013 // The first time a receiver is seen that is a transitioned version of the
1020 // previous monomorphic receiver type, assume the new ElementsKind is the 1014 // previous monomorphic receiver type, assume the new ElementsKind is the
1021 // monomorphic type. This benefits global arrays that only transition 1015 // monomorphic type. This benefits global arrays that only transition
1022 // once, and all call sites accessing them are faster if they remain 1016 // once, and all call sites accessing them are faster if they remain
1023 // monomorphic. If this optimistic assumption is not true, the IC will 1017 // monomorphic. If this optimistic assumption is not true, the IC will
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
1407 Handle<Map> receiver_map(receiver->map(), isolate()); 1401 Handle<Map> receiver_map(receiver->map(), isolate());
1408 if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) { 1402 if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) {
1409 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state 1403 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
1410 // yet will do so and stay there. 1404 // yet will do so and stay there.
1411 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode); 1405 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode);
1412 store_mode = GetNonTransitioningStoreMode(store_mode); 1406 store_mode = GetNonTransitioningStoreMode(store_mode);
1413 return isolate()->stub_cache()->ComputeKeyedStoreElement( 1407 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1414 monomorphic_map, strict_mode(), store_mode); 1408 monomorphic_map, strict_mode(), store_mode);
1415 } 1409 }
1416 1410
1417 MapHandleList target_receiver_maps;
1418 target()->FindAllMaps(&target_receiver_maps);
1419 if (target_receiver_maps.length() == 0) {
1420 // In the case that there is a non-map-specific IC is installed (e.g. keyed
1421 // stores into properties in dictionary mode), then there will be not
1422 // receiver maps in the target.
1423 return generic_stub();
1424 }
1425
1426 // There are several special cases where an IC that is MONOMORPHIC can still 1411 // There are several special cases where an IC that is MONOMORPHIC can still
1427 // transition to a different GetNonTransitioningStoreMode IC that handles a 1412 // transition to a different GetNonTransitioningStoreMode IC that handles a
1428 // superset of the original IC. Handle those here if the receiver map hasn't 1413 // superset of the original IC. Handle those here if the receiver map hasn't
1429 // changed or it has transitioned to a more general kind. 1414 // changed or it has transitioned to a more general kind.
1430 KeyedAccessStoreMode old_store_mode = 1415 KeyedAccessStoreMode old_store_mode =
1431 KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); 1416 KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state());
1432 Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
1433 if (state() == MONOMORPHIC) { 1417 if (state() == MONOMORPHIC) {
1434 // If the "old" and "new" maps are in the same elements map family, stay 1418 // If the "old" and "new" maps are in the same elements map family, stay
1435 // MONOMORPHIC and use the map for the most generic ElementsKind. 1419 // MONOMORPHIC and use the map for the most generic ElementsKind.
1436 Handle<Map> transitioned_receiver_map = receiver_map; 1420 Handle<Map> transitioned_map = receiver_map;
1437 if (IsTransitionStoreMode(store_mode)) { 1421 if (IsTransitionStoreMode(store_mode)) {
1438 transitioned_receiver_map = 1422 transitioned_map = ComputeTransitionedMap(receiver, store_mode);
1439 ComputeTransitionedMap(receiver, store_mode);
1440 } 1423 }
1441 if (IsTransitionOfMonomorphicTarget( 1424 if (IsTransitionOfMonomorphicTarget(first_map(), *transitioned_map)) {
1442 MapToType<HeapType>(transitioned_receiver_map, isolate()))) {
1443 // Element family is the same, use the "worst" case map. 1425 // Element family is the same, use the "worst" case map.
1444 store_mode = GetNonTransitioningStoreMode(store_mode); 1426 store_mode = GetNonTransitioningStoreMode(store_mode);
1445 return isolate()->stub_cache()->ComputeKeyedStoreElement( 1427 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1446 transitioned_receiver_map, strict_mode(), store_mode); 1428 transitioned_map, strict_mode(), store_mode);
1447 } else if (*previous_receiver_map == receiver->map() && 1429 } else if (first_map() == receiver->map() &&
1448 old_store_mode == STANDARD_STORE && 1430 old_store_mode == STANDARD_STORE &&
1449 (IsGrowStoreMode(store_mode) || 1431 (IsGrowStoreMode(store_mode) ||
1450 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 1432 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
1451 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { 1433 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) {
1452 // A "normal" IC that handles stores can switch to a version that can 1434 // A "normal" IC that handles stores can switch to a version that can
1453 // grow at the end of the array, handle OOB accesses or copy COW arrays 1435 // grow at the end of the array, handle OOB accesses or copy COW arrays
1454 // and still stay MONOMORPHIC. 1436 // and still stay MONOMORPHIC.
1455 return isolate()->stub_cache()->ComputeKeyedStoreElement( 1437 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1456 receiver_map, strict_mode(), store_mode); 1438 receiver_map, strict_mode(), store_mode);
1457 } 1439 }
1458 } 1440 }
1459 1441
1460 ASSERT(state() != GENERIC); 1442 ASSERT(state() != GENERIC);
1461 1443
1444 MapHandleList target_receiver_maps;
1445 GetMapsFromTypes(&target_receiver_maps);
1446
1462 bool map_added = 1447 bool map_added =
1463 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); 1448 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
1464 1449
1465 if (IsTransitionStoreMode(store_mode)) { 1450 if (IsTransitionStoreMode(store_mode)) {
1466 Handle<Map> transitioned_receiver_map = 1451 Handle<Map> transitioned_receiver_map =
1467 ComputeTransitionedMap(receiver, store_mode); 1452 ComputeTransitionedMap(receiver, store_mode);
1468 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, 1453 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps,
1469 transitioned_receiver_map); 1454 transitioned_receiver_map);
1470 } 1455 }
1471 1456
(...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after
2708 // types must be supported as a result of the miss. 2693 // types must be supported as a result of the miss.
2709 bool already_monomorphic = stub.IsMonomorphic(); 2694 bool already_monomorphic = stub.IsMonomorphic();
2710 2695
2711 stub.UpdateStatus(object); 2696 stub.UpdateStatus(object);
2712 2697
2713 NilValue nil = stub.GetNilValue(); 2698 NilValue nil = stub.GetNilValue();
2714 2699
2715 // Find or create the specialized stub to support the new set of types. 2700 // Find or create the specialized stub to support the new set of types.
2716 Handle<Code> code; 2701 Handle<Code> code;
2717 if (stub.IsMonomorphic()) { 2702 if (stub.IsMonomorphic()) {
2718 Handle<Map> monomorphic_map(already_monomorphic 2703 Handle<Map> monomorphic_map(already_monomorphic && (first_map() != NULL)
2719 ? target()->FindFirstMap() 2704 ? first_map()
2720 : HeapObject::cast(*object)->map()); 2705 : HeapObject::cast(*object)->map());
2721 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub); 2706 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub);
2722 } else { 2707 } else {
2723 code = stub.GetCode(isolate()); 2708 code = stub.GetCode(isolate());
2724 } 2709 }
2725 set_target(*code); 2710 set_target(*code);
2726 return DoCompareNilSlow(nil, object); 2711 return DoCompareNilSlow(nil, object);
2727 } 2712 }
2728 2713
2729 2714
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2808 #undef ADDR 2793 #undef ADDR
2809 }; 2794 };
2810 2795
2811 2796
2812 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2797 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2813 return IC_utilities[id]; 2798 return IC_utilities[id];
2814 } 2799 }
2815 2800
2816 2801
2817 } } // namespace v8::internal 2802 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698