OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 } | 223 } |
224 | 224 |
225 | 225 |
226 bool IC::AddressIsOptimizedCode() const { | 226 bool IC::AddressIsOptimizedCode() const { |
227 Code* host = | 227 Code* host = |
228 isolate()->inner_pointer_to_code_cache()->GetCacheEntry(address())->code; | 228 isolate()->inner_pointer_to_code_cache()->GetCacheEntry(address())->code; |
229 return host->kind() == Code::OPTIMIZED_FUNCTION; | 229 return host->kind() == Code::OPTIMIZED_FUNCTION; |
230 } | 230 } |
231 | 231 |
232 | 232 |
| 233 bool IC::AddressIsDeoptimizedCode() const { |
| 234 Code* host = |
| 235 isolate()->inner_pointer_to_code_cache()->GetCacheEntry(address())->code; |
| 236 return host->kind() == Code::OPTIMIZED_FUNCTION && |
| 237 host->marked_for_deoptimization(); |
| 238 } |
| 239 |
| 240 |
233 static void LookupForRead(LookupIterator* it) { | 241 static void LookupForRead(LookupIterator* it) { |
234 for (; it->IsFound(); it->Next()) { | 242 for (; it->IsFound(); it->Next()) { |
235 switch (it->state()) { | 243 switch (it->state()) { |
236 case LookupIterator::NOT_FOUND: | 244 case LookupIterator::NOT_FOUND: |
237 case LookupIterator::TRANSITION: | 245 case LookupIterator::TRANSITION: |
238 UNREACHABLE(); | 246 UNREACHABLE(); |
239 case LookupIterator::JSPROXY: | 247 case LookupIterator::JSPROXY: |
240 return; | 248 return; |
241 case LookupIterator::INTERCEPTOR: { | 249 case LookupIterator::INTERCEPTOR: { |
242 // If there is a getter, return; otherwise loop to perform the lookup. | 250 // If there is a getter, return; otherwise loop to perform the lookup. |
(...skipping 2235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2478 | 2486 |
2479 // Compute the actual result using the builtin for the binary operation. | 2487 // Compute the actual result using the builtin for the binary operation. |
2480 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( | 2488 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( |
2481 TokenToJSBuiltin(state.op())); | 2489 TokenToJSBuiltin(state.op())); |
2482 Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate()); | 2490 Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate()); |
2483 Handle<Object> result; | 2491 Handle<Object> result; |
2484 ASSIGN_RETURN_ON_EXCEPTION( | 2492 ASSIGN_RETURN_ON_EXCEPTION( |
2485 isolate(), result, Execution::Call(isolate(), function, left, 1, &right), | 2493 isolate(), result, Execution::Call(isolate(), function, left, 1, &right), |
2486 Object); | 2494 Object); |
2487 | 2495 |
| 2496 // Do not try to update the target if the code was marked for lazy |
| 2497 // deoptimization. (Since we do not relocate addresses in these |
| 2498 // code objects, an attempt to access the target could fail.) |
| 2499 if (AddressIsDeoptimizedCode()) { |
| 2500 return result; |
| 2501 } |
| 2502 |
2488 // Execution::Call can execute arbitrary JavaScript, hence potentially | 2503 // Execution::Call can execute arbitrary JavaScript, hence potentially |
2489 // update the state of this very IC, so we must update the stored state. | 2504 // update the state of this very IC, so we must update the stored state. |
2490 UpdateTarget(); | 2505 UpdateTarget(); |
| 2506 |
2491 // Compute the new state. | 2507 // Compute the new state. |
2492 BinaryOpICState old_state(isolate(), target()->extra_ic_state()); | 2508 BinaryOpICState old_state(isolate(), target()->extra_ic_state()); |
2493 state.Update(left, right, result); | 2509 state.Update(left, right, result); |
2494 | 2510 |
2495 // Check if we have a string operation here. | 2511 // Check if we have a string operation here. |
2496 Handle<Code> target; | 2512 Handle<Code> target; |
2497 if (!allocation_site.is_null() || state.ShouldCreateAllocationMementos()) { | 2513 if (!allocation_site.is_null() || state.ShouldCreateAllocationMementos()) { |
2498 // Setup the allocation site on-demand. | 2514 // Setup the allocation site on-demand. |
2499 if (allocation_site.is_null()) { | 2515 if (allocation_site.is_null()) { |
2500 allocation_site = isolate()->factory()->NewAllocationSite(); | 2516 allocation_site = isolate()->factory()->NewAllocationSite(); |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2967 static const Address IC_utilities[] = { | 2983 static const Address IC_utilities[] = { |
2968 #define ADDR(name) FUNCTION_ADDR(name), | 2984 #define ADDR(name) FUNCTION_ADDR(name), |
2969 IC_UTIL_LIST(ADDR) NULL | 2985 IC_UTIL_LIST(ADDR) NULL |
2970 #undef ADDR | 2986 #undef ADDR |
2971 }; | 2987 }; |
2972 | 2988 |
2973 | 2989 |
2974 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } | 2990 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } |
2975 } | 2991 } |
2976 } // namespace v8::internal | 2992 } // namespace v8::internal |
OLD | NEW |