OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 23 matching lines...) Expand all Loading... |
34 #include "ic-inl.h" | 34 #include "ic-inl.h" |
35 #include "runtime.h" | 35 #include "runtime.h" |
36 #include "stub-cache.h" | 36 #include "stub-cache.h" |
37 | 37 |
38 namespace v8 { namespace internal { | 38 namespace v8 { namespace internal { |
39 | 39 |
40 #ifdef DEBUG | 40 #ifdef DEBUG |
41 static char TransitionMarkFromState(IC::State state) { | 41 static char TransitionMarkFromState(IC::State state) { |
42 switch (state) { | 42 switch (state) { |
43 case UNINITIALIZED: return '0'; | 43 case UNINITIALIZED: return '0'; |
| 44 case UNINITIALIZED_IN_LOOP: return 'L'; |
44 case PREMONOMORPHIC: return '0'; | 45 case PREMONOMORPHIC: return '0'; |
45 case MONOMORPHIC: return '1'; | 46 case MONOMORPHIC: return '1'; |
46 case MONOMORPHIC_PROTOTYPE_FAILURE: return '^'; | 47 case MONOMORPHIC_PROTOTYPE_FAILURE: return '^'; |
47 case MEGAMORPHIC: return 'N'; | 48 case MEGAMORPHIC: return 'N'; |
48 | 49 |
49 // We never see the debugger states here, because the state is | 50 // We never see the debugger states here, because the state is |
50 // computed from the original code - not the patched code. Let | 51 // computed from the original code - not the patched code. Let |
51 // these cases fall through to the unreachable code below. | 52 // these cases fall through to the unreachable code below. |
52 case DEBUG_BREAK: break; | 53 case DEBUG_BREAK: break; |
53 case DEBUG_PREPARE_STEP_IN: break; | 54 case DEBUG_PREPARE_STEP_IN: break; |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 case Code::KEYED_LOAD_IC: return KeyedLoadIC::Clear(address, target); | 217 case Code::KEYED_LOAD_IC: return KeyedLoadIC::Clear(address, target); |
217 case Code::STORE_IC: return StoreIC::Clear(address, target); | 218 case Code::STORE_IC: return StoreIC::Clear(address, target); |
218 case Code::KEYED_STORE_IC: return KeyedStoreIC::Clear(address, target); | 219 case Code::KEYED_STORE_IC: return KeyedStoreIC::Clear(address, target); |
219 case Code::CALL_IC: return CallIC::Clear(address, target); | 220 case Code::CALL_IC: return CallIC::Clear(address, target); |
220 default: UNREACHABLE(); | 221 default: UNREACHABLE(); |
221 } | 222 } |
222 } | 223 } |
223 | 224 |
224 | 225 |
225 void CallIC::Clear(Address address, Code* target) { | 226 void CallIC::Clear(Address address, Code* target) { |
226 if (target->ic_state() == UNINITIALIZED) return; | 227 State state = target->ic_state(); |
| 228 if (state == UNINITIALIZED || state == UNINITIALIZED_IN_LOOP) return; |
227 Code* code = StubCache::FindCallInitialize(target->arguments_count()); | 229 Code* code = StubCache::FindCallInitialize(target->arguments_count()); |
228 SetTargetAtAddress(address, code); | 230 SetTargetAtAddress(address, code); |
229 } | 231 } |
230 | 232 |
231 | 233 |
232 void KeyedLoadIC::Clear(Address address, Code* target) { | 234 void KeyedLoadIC::Clear(Address address, Code* target) { |
233 if (target->ic_state() == UNINITIALIZED) return; | 235 if (target->ic_state() == UNINITIALIZED) return; |
234 SetTargetAtAddress(address, initialize_stub()); | 236 SetTargetAtAddress(address, initialize_stub()); |
235 } | 237 } |
236 | 238 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 default: | 429 default: |
428 return; | 430 return; |
429 } | 431 } |
430 } | 432 } |
431 | 433 |
432 // If we're unable to compute the stub (not enough memory left), we | 434 // If we're unable to compute the stub (not enough memory left), we |
433 // simply avoid updating the caches. | 435 // simply avoid updating the caches. |
434 if (code->IsFailure()) return; | 436 if (code->IsFailure()) return; |
435 | 437 |
436 // Patch the call site depending on the state of the cache. | 438 // Patch the call site depending on the state of the cache. |
437 if (state == UNINITIALIZED || state == PREMONOMORPHIC || | 439 if (state == UNINITIALIZED || state == UNINITIALIZED_IN_LOOP || |
438 state == MONOMORPHIC || state == MONOMORPHIC_PROTOTYPE_FAILURE) { | 440 state == PREMONOMORPHIC || state == MONOMORPHIC || |
| 441 state == MONOMORPHIC_PROTOTYPE_FAILURE) { |
439 set_target(Code::cast(code)); | 442 set_target(Code::cast(code)); |
440 } | 443 } |
441 | 444 |
442 #ifdef DEBUG | 445 #ifdef DEBUG |
443 TraceIC("CallIC", name, state, target()); | 446 TraceIC("CallIC", name, state, target()); |
444 #endif | 447 #endif |
445 } | 448 } |
446 | 449 |
447 | 450 |
448 Object* LoadIC::Load(State state, Handle<Object> object, Handle<String> name) { | 451 Object* LoadIC::Load(State state, Handle<Object> object, Handle<String> name) { |
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1037 // ---------------------------------------------------------------------------- | 1040 // ---------------------------------------------------------------------------- |
1038 // Static IC stub generators. | 1041 // Static IC stub generators. |
1039 // | 1042 // |
1040 | 1043 |
1041 // Used from ic_<arch>.cc. | 1044 // Used from ic_<arch>.cc. |
1042 Object* CallIC_Miss(Arguments args) { | 1045 Object* CallIC_Miss(Arguments args) { |
1043 NoHandleAllocation na; | 1046 NoHandleAllocation na; |
1044 ASSERT(args.length() == 2); | 1047 ASSERT(args.length() == 2); |
1045 CallIC ic; | 1048 CallIC ic; |
1046 IC::State state = IC::StateFrom(ic.target(), args[0]); | 1049 IC::State state = IC::StateFrom(ic.target(), args[0]); |
1047 return ic.LoadFunction(state, args.at<Object>(0), args.at<String>(1)); | 1050 Object* result = |
| 1051 ic.LoadFunction(state, args.at<Object>(0), args.at<String>(1)); |
| 1052 if (state != UNINITIALIZED_IN_LOOP || !result->IsJSFunction()) |
| 1053 return result; |
| 1054 |
| 1055 // Compile the function with the knowledge that it's called from |
| 1056 // within a loop. This enables further optimization of the function. |
| 1057 HandleScope scope; |
| 1058 Handle<JSFunction> function = Handle<JSFunction>(JSFunction::cast(result)); |
| 1059 if (!function->is_compiled()) CompileLazyInLoop(function, CLEAR_EXCEPTION); |
| 1060 return *function; |
1048 } | 1061 } |
1049 | 1062 |
1050 | 1063 |
1051 void CallIC::GenerateInitialize(MacroAssembler* masm, int argc) { | 1064 void CallIC::GenerateInitialize(MacroAssembler* masm, int argc) { |
1052 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); | 1065 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); |
1053 } | 1066 } |
1054 | 1067 |
1055 | 1068 |
1056 void CallIC::GeneratePreMonomorphic(MacroAssembler* masm, int argc) { | 1069 void CallIC::GeneratePreMonomorphic(MacroAssembler* masm, int argc) { |
1057 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); | 1070 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1186 #undef ADDR | 1199 #undef ADDR |
1187 }; | 1200 }; |
1188 | 1201 |
1189 | 1202 |
1190 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 1203 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
1191 return IC_utilities[id]; | 1204 return IC_utilities[id]; |
1192 } | 1205 } |
1193 | 1206 |
1194 | 1207 |
1195 } } // namespace v8::internal | 1208 } } // namespace v8::internal |
OLD | NEW |