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

Side by Side Diff: src/ic.cc

Issue 8883011: Implement ICs for constructor calls. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | src/objects-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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 // We never see the debugger states here, because the state is 51 // We never see the debugger states here, because the state is
52 // computed from the original code - not the patched code. Let 52 // computed from the original code - not the patched code. Let
53 // these cases fall through to the unreachable code below. 53 // these cases fall through to the unreachable code below.
54 case DEBUG_BREAK: break; 54 case DEBUG_BREAK: break;
55 case DEBUG_PREPARE_STEP_IN: break; 55 case DEBUG_PREPARE_STEP_IN: break;
56 } 56 }
57 UNREACHABLE(); 57 UNREACHABLE();
58 return 0; 58 return 0;
59 } 59 }
60 60
61 static const char* NameForCallIC(Code::Kind kind,
62 Code::ExtraICState extra_ic_state) {
63 return CallICBase::ConstructCall::decode(extra_ic_state)
64 ? (kind == Code::CALL_IC ? "ConstructIC" : "KeyedConstructIC")
65 : (kind == Code::CALL_IC ? "CallIC" : "KeyedCallIC");
66 }
67
61 void IC::TraceIC(const char* type, 68 void IC::TraceIC(const char* type,
62 Handle<Object> name, 69 Handle<Object> name,
63 State old_state, 70 State old_state,
64 Code* new_target) { 71 Code* new_target) {
65 if (FLAG_trace_ic) { 72 if (FLAG_trace_ic) {
66 State new_state = StateFrom(new_target, 73 State new_state = StateFrom(new_target,
67 HEAP->undefined_value(), 74 HEAP->undefined_value(),
68 HEAP->undefined_value()); 75 HEAP->undefined_value());
69 PrintF("[%s in ", type); 76 PrintF("[%s in ", type);
70 StackFrameIterator it; 77 StackFrameIterator it;
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 302
296 303
297 void IC::Clear(Address address) { 304 void IC::Clear(Address address) {
298 Code* target = GetTargetAtAddress(address); 305 Code* target = GetTargetAtAddress(address);
299 306
300 // Don't clear debug break inline cache as it will remove the break point. 307 // Don't clear debug break inline cache as it will remove the break point.
301 if (target->ic_state() == DEBUG_BREAK) return; 308 if (target->ic_state() == DEBUG_BREAK) return;
302 309
303 switch (target->kind()) { 310 switch (target->kind()) {
304 case Code::LOAD_IC: return LoadIC::Clear(address, target); 311 case Code::LOAD_IC: return LoadIC::Clear(address, target);
305 case Code::KEYED_LOAD_IC: 312 case Code::KEYED_LOAD_IC: return KeyedLoadIC::Clear(address, target);
306 return KeyedLoadIC::Clear(address, target);
307 case Code::STORE_IC: return StoreIC::Clear(address, target); 313 case Code::STORE_IC: return StoreIC::Clear(address, target);
308 case Code::KEYED_STORE_IC: 314 case Code::KEYED_STORE_IC: return KeyedStoreIC::Clear(address, target);
309 return KeyedStoreIC::Clear(address, target);
310 case Code::CALL_IC: return CallIC::Clear(address, target); 315 case Code::CALL_IC: return CallIC::Clear(address, target);
311 case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target); 316 case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target);
312 case Code::UNARY_OP_IC: 317 case Code::UNARY_OP_IC:
313 case Code::BINARY_OP_IC: 318 case Code::BINARY_OP_IC:
314 case Code::COMPARE_IC: 319 case Code::COMPARE_IC:
315 case Code::TO_BOOLEAN_IC: 320 case Code::TO_BOOLEAN_IC:
316 // Clearing these is tricky and does not 321 // Clearing these is tricky and does not
317 // make any performance difference. 322 // make any performance difference.
318 return; 323 return;
319 default: UNREACHABLE(); 324 default: UNREACHABLE();
320 } 325 }
321 } 326 }
322 327
323 328
324 void CallICBase::Clear(Address address, Code* target) { 329 void CallICBase::Clear(Address address, Code* target) {
325 bool contextual = CallICBase::Contextual::decode(target->extra_ic_state()); 330 bool contextual = CallICBase::Contextual::decode(target->extra_ic_state());
331 bool construct = CallICBase::ConstructCall::decode(target->extra_ic_state());
332 RelocInfo::Mode mode = construct ? RelocInfo::CONSTRUCT_CALL :
333 (contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET);
326 State state = target->ic_state(); 334 State state = target->ic_state();
327 if (state == UNINITIALIZED) return; 335 if (state == UNINITIALIZED) return;
328 Code* code = 336 Code* code =
329 Isolate::Current()->stub_cache()->FindCallInitialize( 337 Isolate::Current()->stub_cache()->FindCallInitialize(
330 target->arguments_count(), 338 target->arguments_count(),
331 contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET, 339 mode,
332 target->kind()); 340 target->kind());
333 SetTargetAtAddress(address, code); 341 SetTargetAtAddress(address, code);
334 } 342 }
335 343
336 344
337 void KeyedLoadIC::Clear(Address address, Code* target) { 345 void KeyedLoadIC::Clear(Address address, Code* target) {
338 if (target->ic_state() == UNINITIALIZED) return; 346 if (target->ic_state() == UNINITIALIZED) return;
339 // Make sure to also clear the map used in inline fast cases. If we 347 // Make sure to also clear the map used in inline fast cases. If we
340 // do not clear these maps, cached code can keep objects alive 348 // do not clear these maps, cached code can keep objects alive
341 // through the embedded maps. 349 // through the embedded maps.
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 // Cache code holding map should be consistent with 704 // Cache code holding map should be consistent with
697 // GenerateMonomorphicCacheProbe. It is not the map which holds the stub. 705 // GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
698 Handle<JSObject> cache_object = object->IsJSObject() 706 Handle<JSObject> cache_object = object->IsJSObject()
699 ? Handle<JSObject>::cast(object) 707 ? Handle<JSObject>::cast(object)
700 : Handle<JSObject>(JSObject::cast(object->GetPrototype())); 708 : Handle<JSObject>(JSObject::cast(object->GetPrototype()));
701 // Update the stub cache. 709 // Update the stub cache.
702 isolate()->stub_cache()->Set(*name, cache_object->map(), *code); 710 isolate()->stub_cache()->Set(*name, cache_object->map(), *code);
703 } 711 }
704 712
705 if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE; 713 if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE;
706 TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", 714 TRACE_IC(NameForCallIC(kind_, extra_ic_state), name, state, target());
707 name, state, target());
708 } 715 }
709 716
710 717
711 MaybeObject* KeyedCallIC::LoadFunction(State state, 718 MaybeObject* KeyedCallIC::LoadFunction(State state,
719 Code::ExtraICState extra_ic_state,
712 Handle<Object> object, 720 Handle<Object> object,
713 Handle<Object> key) { 721 Handle<Object> key) {
714 if (key->IsSymbol()) { 722 if (key->IsSymbol()) {
715 return CallICBase::LoadFunction(state, 723 return CallICBase::LoadFunction(state,
716 Code::kNoExtraICState, 724 extra_ic_state,
717 object, 725 object,
718 Handle<String>::cast(key)); 726 Handle<String>::cast(key));
719 } 727 }
720 728
721 if (object->IsUndefined() || object->IsNull()) { 729 if (object->IsUndefined() || object->IsNull()) {
722 return TypeError("non_object_property_call", object, key); 730 return TypeError("non_object_property_call", object, key);
723 } 731 }
724 732
725 if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) { 733 if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) {
726 int argc = target()->arguments_count(); 734 int argc = target()->arguments_count();
727 Handle<Map> map = 735 Handle<Map> map =
728 isolate()->factory()->non_strict_arguments_elements_map(); 736 isolate()->factory()->non_strict_arguments_elements_map();
729 if (object->IsJSObject() && 737 if (object->IsJSObject() &&
730 Handle<JSObject>::cast(object)->elements()->map() == *map) { 738 Handle<JSObject>::cast(object)->elements()->map() == *map) {
731 Handle<Code> code = isolate()->stub_cache()->ComputeCallArguments( 739 Handle<Code> code = isolate()->stub_cache()->ComputeCallArguments(
732 argc, Code::KEYED_CALL_IC); 740 argc, Code::KEYED_CALL_IC, extra_ic_state);
733 set_target(*code); 741 set_target(*code);
734 TRACE_IC("KeyedCallIC", key, state, target()); 742 TRACE_IC(NameForCallIC(kind_, extra_ic_state), key, state, target());
735 } else if (!object->IsAccessCheckNeeded()) { 743 } else if (!object->IsAccessCheckNeeded()) {
736 Handle<Code> code = isolate()->stub_cache()->ComputeCallMegamorphic( 744 Handle<Code> code = isolate()->stub_cache()->ComputeCallMegamorphic(
737 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); 745 argc, Code::KEYED_CALL_IC, extra_ic_state);
738 set_target(*code); 746 set_target(*code);
739 TRACE_IC("KeyedCallIC", key, state, target()); 747 TRACE_IC(NameForCallIC(kind_, extra_ic_state), key, state, target());
740 } 748 }
741 } 749 }
742 750
743 Handle<Object> result = GetProperty(object, key); 751 Handle<Object> result = GetProperty(object, key);
744 RETURN_IF_EMPTY_HANDLE(isolate(), result); 752 RETURN_IF_EMPTY_HANDLE(isolate(), result);
745 753
746 // Make receiver an object if the callee requires it. Strict mode or builtin 754 // Make receiver an object if the callee requires it. Strict mode or builtin
747 // functions do not wrap the receiver, non-strict functions and objects 755 // functions do not wrap the receiver, non-strict functions and objects
748 // called as functions do. 756 // called as functions do.
749 ReceiverToObjectIfRequired(result, object); 757 ReceiverToObjectIfRequired(result, object);
(...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after
1805 return *function; 1813 return *function;
1806 } 1814 }
1807 1815
1808 1816
1809 // Used from ic-<arch>.cc. 1817 // Used from ic-<arch>.cc.
1810 RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) { 1818 RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) {
1811 HandleScope scope(isolate); 1819 HandleScope scope(isolate);
1812 ASSERT(args.length() == 2); 1820 ASSERT(args.length() == 2);
1813 KeyedCallIC ic(isolate); 1821 KeyedCallIC ic(isolate);
1814 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1822 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
1815 MaybeObject* maybe_result = 1823 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
1816 ic.LoadFunction(state, args.at<Object>(0), args.at<Object>(1)); 1824 MaybeObject* maybe_result = ic.LoadFunction(state,
1825 extra_ic_state,
1826 args.at<Object>(0),
1827 args.at<Object>(1));
1817 // Result could be a function or a failure. 1828 // Result could be a function or a failure.
1818 JSFunction* raw_function = NULL; 1829 JSFunction* raw_function = NULL;
1819 if (!maybe_result->To(&raw_function)) return maybe_result; 1830 if (!maybe_result->To(&raw_function)) return maybe_result;
1820 1831
1821 if (raw_function->is_compiled()) return raw_function; 1832 if (raw_function->is_compiled()) return raw_function;
1822 1833
1823 Handle<JSFunction> function(raw_function); 1834 Handle<JSFunction> function(raw_function);
1824 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); 1835 JSFunction::CompileLazy(function, CLEAR_EXCEPTION);
1825 return *function; 1836 return *function;
1826 } 1837 }
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
2388 #undef ADDR 2399 #undef ADDR
2389 }; 2400 };
2390 2401
2391 2402
2392 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2403 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2393 return IC_utilities[id]; 2404 return IC_utilities[id];
2394 } 2405 }
2395 2406
2396 2407
2397 } } // namespace v8::internal 2408 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698