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

Side by Side Diff: src/ic.cc

Issue 2813002: Only update the stub cache tables with monomorphic stubs used by... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 6 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 | « no previous file | src/stub-cache.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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 const int argc = this->target()->arguments_count(); 380 const int argc = this->target()->arguments_count();
381 StackFrameLocator locator; 381 StackFrameLocator locator;
382 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 382 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
383 int index = frame->ComputeExpressionsCount() - (argc + 1); 383 int index = frame->ComputeExpressionsCount() - (argc + 1);
384 frame->SetExpression(index, *target); 384 frame->SetExpression(index, *target);
385 } 385 }
386 386
387 return *delegate; 387 return *delegate;
388 } 388 }
389 389
390
390 void CallICBase::ReceiverToObject(Handle<Object> object) { 391 void CallICBase::ReceiverToObject(Handle<Object> object) {
391 HandleScope scope; 392 HandleScope scope;
392 Handle<Object> receiver(object); 393 Handle<Object> receiver(object);
393 394
394 // Change the receiver to the result of calling ToObject on it. 395 // Change the receiver to the result of calling ToObject on it.
395 const int argc = this->target()->arguments_count(); 396 const int argc = this->target()->arguments_count();
396 StackFrameLocator locator; 397 StackFrameLocator locator;
397 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 398 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
398 int index = frame->ComputeExpressionsCount() - (argc + 1); 399 int index = frame->ComputeExpressionsCount() - (argc + 1);
399 frame->SetExpression(index, *Factory::ToObject(object)); 400 frame->SetExpression(index, *Factory::ToObject(object));
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 // If we're unable to compute the stub (not enough memory left), we 582 // If we're unable to compute the stub (not enough memory left), we
582 // simply avoid updating the caches. 583 // simply avoid updating the caches.
583 if (code == NULL || code->IsFailure()) return; 584 if (code == NULL || code->IsFailure()) return;
584 585
585 // Patch the call site depending on the state of the cache. 586 // Patch the call site depending on the state of the cache.
586 if (state == UNINITIALIZED || 587 if (state == UNINITIALIZED ||
587 state == PREMONOMORPHIC || 588 state == PREMONOMORPHIC ||
588 state == MONOMORPHIC || 589 state == MONOMORPHIC ||
589 state == MONOMORPHIC_PROTOTYPE_FAILURE) { 590 state == MONOMORPHIC_PROTOTYPE_FAILURE) {
590 set_target(Code::cast(code)); 591 set_target(Code::cast(code));
592 } else if (state == MEGAMORPHIC) {
593 // Update the stub cache.
594 StubCache::Set(*name, GetCodeCacheMapForObject(*object), Code::cast(code));
591 } 595 }
592 596
593 #ifdef DEBUG 597 #ifdef DEBUG
594 TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", 598 TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC",
595 name, state, target(), in_loop ? " (in-loop)" : ""); 599 name, state, target(), in_loop ? " (in-loop)" : "");
596 #endif 600 #endif
597 } 601 }
598 602
599 603
600 Object* KeyedCallIC::LoadFunction(State state, 604 Object* KeyedCallIC::LoadFunction(State state,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 #endif 661 #endif
658 Map* map = HeapObject::cast(*object)->map(); 662 Map* map = HeapObject::cast(*object)->map();
659 if (object->IsString()) { 663 if (object->IsString()) {
660 const int offset = String::kLengthOffset; 664 const int offset = String::kLengthOffset;
661 PatchInlinedLoad(address(), map, offset); 665 PatchInlinedLoad(address(), map, offset);
662 } 666 }
663 667
664 Code* target = NULL; 668 Code* target = NULL;
665 target = Builtins::builtin(Builtins::LoadIC_StringLength); 669 target = Builtins::builtin(Builtins::LoadIC_StringLength);
666 set_target(target); 670 set_target(target);
667 StubCache::Set(*name, map, target);
668 return Smi::FromInt(String::cast(*object)->length()); 671 return Smi::FromInt(String::cast(*object)->length());
669 } 672 }
670 673
671 // Use specialized code for getting the length of arrays. 674 // Use specialized code for getting the length of arrays.
672 if (object->IsJSArray() && name->Equals(Heap::length_symbol())) { 675 if (object->IsJSArray() && name->Equals(Heap::length_symbol())) {
673 #ifdef DEBUG 676 #ifdef DEBUG
674 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n"); 677 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
675 #endif 678 #endif
676 Map* map = HeapObject::cast(*object)->map(); 679 Map* map = HeapObject::cast(*object)->map();
677 const int offset = JSArray::kLengthOffset; 680 const int offset = JSArray::kLengthOffset;
678 PatchInlinedLoad(address(), map, offset); 681 PatchInlinedLoad(address(), map, offset);
679 682
680 Code* target = Builtins::builtin(Builtins::LoadIC_ArrayLength); 683 Code* target = Builtins::builtin(Builtins::LoadIC_ArrayLength);
681 set_target(target); 684 set_target(target);
682 StubCache::Set(*name, map, target);
683 return JSArray::cast(*object)->length(); 685 return JSArray::cast(*object)->length();
684 } 686 }
685 687
686 // Use specialized code for getting prototype of functions. 688 // Use specialized code for getting prototype of functions.
687 if (object->IsJSFunction() && name->Equals(Heap::prototype_symbol()) && 689 if (object->IsJSFunction() && name->Equals(Heap::prototype_symbol()) &&
688 JSFunction::cast(*object)->should_have_prototype()) { 690 JSFunction::cast(*object)->should_have_prototype()) {
689 #ifdef DEBUG 691 #ifdef DEBUG
690 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); 692 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n");
691 #endif 693 #endif
692 Code* target = Builtins::builtin(Builtins::LoadIC_FunctionPrototype); 694 Code* target = Builtins::builtin(Builtins::LoadIC_FunctionPrototype);
693 set_target(target); 695 set_target(target);
694 StubCache::Set(*name, HeapObject::cast(*object)->map(), target);
695 return Accessors::FunctionGetPrototype(*object, 0); 696 return Accessors::FunctionGetPrototype(*object, 0);
696 } 697 }
697 } 698 }
698 699
699 // Check if the name is trivially convertible to an index and get 700 // Check if the name is trivially convertible to an index and get
700 // the element if so. 701 // the element if so.
701 uint32_t index; 702 uint32_t index;
702 if (name->AsArrayIndex(&index)) return object->GetElement(index); 703 if (name->AsArrayIndex(&index)) return object->GetElement(index);
703 704
704 // Named lookup in the object. 705 // Named lookup in the object.
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 // If we're unable to compute the stub (not enough memory left), we 841 // If we're unable to compute the stub (not enough memory left), we
841 // simply avoid updating the caches. 842 // simply avoid updating the caches.
842 if (code == NULL || code->IsFailure()) return; 843 if (code == NULL || code->IsFailure()) return;
843 844
844 // Patch the call site depending on the state of the cache. 845 // Patch the call site depending on the state of the cache.
845 if (state == UNINITIALIZED || state == PREMONOMORPHIC || 846 if (state == UNINITIALIZED || state == PREMONOMORPHIC ||
846 state == MONOMORPHIC_PROTOTYPE_FAILURE) { 847 state == MONOMORPHIC_PROTOTYPE_FAILURE) {
847 set_target(Code::cast(code)); 848 set_target(Code::cast(code));
848 } else if (state == MONOMORPHIC) { 849 } else if (state == MONOMORPHIC) {
849 set_target(megamorphic_stub()); 850 set_target(megamorphic_stub());
851 } else if (state == MEGAMORPHIC) {
852 // Update the stub cache.
853 StubCache::Set(*name, GetCodeCacheMapForObject(*object), Code::cast(code));
850 } 854 }
851 855
852 #ifdef DEBUG 856 #ifdef DEBUG
853 TraceIC("LoadIC", name, state, target()); 857 TraceIC("LoadIC", name, state, target());
854 #endif 858 #endif
855 } 859 }
856 860
857 861
858 Object* KeyedLoadIC::Load(State state, 862 Object* KeyedLoadIC::Load(State state,
859 Handle<Object> object, 863 Handle<Object> object,
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1103 1107
1104 // Check if the given name is an array index. 1108 // Check if the given name is an array index.
1105 uint32_t index; 1109 uint32_t index;
1106 if (name->AsArrayIndex(&index)) { 1110 if (name->AsArrayIndex(&index)) {
1107 HandleScope scope; 1111 HandleScope scope;
1108 Handle<Object> result = SetElement(receiver, index, value); 1112 Handle<Object> result = SetElement(receiver, index, value);
1109 if (result.is_null()) return Failure::Exception(); 1113 if (result.is_null()) return Failure::Exception();
1110 return *value; 1114 return *value;
1111 } 1115 }
1112 1116
1113
1114 // Use specialized code for setting the length of arrays. 1117 // Use specialized code for setting the length of arrays.
1115 if (receiver->IsJSArray() 1118 if (receiver->IsJSArray()
1116 && name->Equals(Heap::length_symbol()) 1119 && name->Equals(Heap::length_symbol())
1117 && receiver->AllowsSetElementsLength()) { 1120 && receiver->AllowsSetElementsLength()) {
1118 #ifdef DEBUG 1121 #ifdef DEBUG
1119 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n"); 1122 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
1120 #endif 1123 #endif
1121 Code* target = Builtins::builtin(Builtins::StoreIC_ArrayLength); 1124 Code* target = Builtins::builtin(Builtins::StoreIC_ArrayLength);
1122 set_target(target); 1125 set_target(target);
1123 StubCache::Set(*name, HeapObject::cast(*object)->map(), target);
1124 return receiver->SetProperty(*name, *value, NONE); 1126 return receiver->SetProperty(*name, *value, NONE);
1125 } 1127 }
1126 1128
1127 // Lookup the property locally in the receiver. 1129 // Lookup the property locally in the receiver.
1128 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) { 1130 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
1129 LookupResult lookup; 1131 LookupResult lookup;
1130 if (LookupForWrite(*receiver, *name, &lookup)) { 1132 if (LookupForWrite(*receiver, *name, &lookup)) {
1131 UpdateCaches(&lookup, state, receiver, name, value); 1133 UpdateCaches(&lookup, state, receiver, name, value);
1132 } 1134 }
1133 } 1135 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 } 1203 }
1202 1204
1203 // If we're unable to compute the stub (not enough memory left), we 1205 // If we're unable to compute the stub (not enough memory left), we
1204 // simply avoid updating the caches. 1206 // simply avoid updating the caches.
1205 if (code == NULL || code->IsFailure()) return; 1207 if (code == NULL || code->IsFailure()) return;
1206 1208
1207 // Patch the call site depending on the state of the cache. 1209 // Patch the call site depending on the state of the cache.
1208 if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) { 1210 if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) {
1209 set_target(Code::cast(code)); 1211 set_target(Code::cast(code));
1210 } else if (state == MONOMORPHIC) { 1212 } else if (state == MONOMORPHIC) {
1211 // Only move to mega morphic if the target changes. 1213 // Only move to megamorphic if the target changes.
1212 if (target() != Code::cast(code)) set_target(megamorphic_stub()); 1214 if (target() != Code::cast(code)) set_target(megamorphic_stub());
1215 } else if (state == MEGAMORPHIC) {
1216 // Update the stub cache.
1217 StubCache::Set(*name, receiver->map(), Code::cast(code));
1213 } 1218 }
1214 1219
1215 #ifdef DEBUG 1220 #ifdef DEBUG
1216 TraceIC("StoreIC", name, state, target()); 1221 TraceIC("StoreIC", name, state, target());
1217 #endif 1222 #endif
1218 } 1223 }
1219 1224
1220 1225
1221 Object* KeyedStoreIC::Store(State state, 1226 Object* KeyedStoreIC::Store(State state,
1222 Handle<Object> object, 1227 Handle<Object> object,
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 #undef ADDR 1595 #undef ADDR
1591 }; 1596 };
1592 1597
1593 1598
1594 Address IC::AddressFromUtilityId(IC::UtilityId id) { 1599 Address IC::AddressFromUtilityId(IC::UtilityId id) {
1595 return IC_utilities[id]; 1600 return IC_utilities[id];
1596 } 1601 }
1597 1602
1598 1603
1599 } } // namespace v8::internal 1604 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/stub-cache.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698