| 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 |