| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset); | 137 pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset); |
| 138 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); | 138 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); |
| 139 } | 139 } |
| 140 #ifdef DEBUG | 140 #ifdef DEBUG |
| 141 StackFrameIterator it(isolate); | 141 StackFrameIterator it(isolate); |
| 142 for (int i = 0; i < depth + 1; i++) it.Advance(); | 142 for (int i = 0; i < depth + 1; i++) it.Advance(); |
| 143 StackFrame* frame = it.frame(); | 143 StackFrame* frame = it.frame(); |
| 144 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); | 144 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); |
| 145 #endif | 145 #endif |
| 146 fp_ = fp; | 146 fp_ = fp; |
| 147 pc_address_ = pc_address; | 147 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); |
| 148 } | 148 } |
| 149 | 149 |
| 150 | 150 |
| 151 #ifdef ENABLE_DEBUGGER_SUPPORT | 151 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 152 Address IC::OriginalCodeAddress() const { | 152 Address IC::OriginalCodeAddress() const { |
| 153 HandleScope scope(isolate()); | 153 HandleScope scope(isolate()); |
| 154 // Compute the JavaScript frame for the frame pointer of this IC | 154 // Compute the JavaScript frame for the frame pointer of this IC |
| 155 // structure. We need this to be able to find the function | 155 // structure. We need this to be able to find the function |
| 156 // corresponding to the frame. | 156 // corresponding to the frame. |
| 157 StackFrameIterator it(isolate()); | 157 StackFrameIterator it(isolate()); |
| (...skipping 1503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1661 Handle<JSObject> receiver, | 1661 Handle<JSObject> receiver, |
| 1662 Handle<String> name, | 1662 Handle<String> name, |
| 1663 Handle<Object> value) { | 1663 Handle<Object> value) { |
| 1664 ASSERT(!receiver->IsJSGlobalProxy()); | 1664 ASSERT(!receiver->IsJSGlobalProxy()); |
| 1665 ASSERT(lookup->IsFound()); | 1665 ASSERT(lookup->IsFound()); |
| 1666 | 1666 |
| 1667 // These are not cacheable, so we never see such LookupResults here. | 1667 // These are not cacheable, so we never see such LookupResults here. |
| 1668 ASSERT(!lookup->IsHandler()); | 1668 ASSERT(!lookup->IsHandler()); |
| 1669 | 1669 |
| 1670 Handle<Code> code = ComputeStoreMonomorphic( | 1670 Handle<Code> code = ComputeStoreMonomorphic( |
| 1671 lookup, strict_mode, receiver, name); | 1671 lookup, strict_mode, receiver, name, value); |
| 1672 if (code.is_null()) { | 1672 if (code.is_null()) { |
| 1673 Handle<Code> stub = strict_mode == kStrictMode | 1673 Handle<Code> stub = strict_mode == kStrictMode |
| 1674 ? generic_stub_strict() : generic_stub(); | 1674 ? generic_stub_strict() : generic_stub(); |
| 1675 set_target(*stub); | 1675 set_target(*stub); |
| 1676 return; | 1676 return; |
| 1677 } | 1677 } |
| 1678 | 1678 |
| 1679 PatchCache(state, strict_mode, receiver, name, code); | 1679 PatchCache(state, strict_mode, receiver, name, code); |
| 1680 TRACE_IC("StoreIC", name, state, target()); | 1680 TRACE_IC("StoreIC", name, state, target()); |
| 1681 } | 1681 } |
| 1682 | 1682 |
| 1683 | 1683 |
| 1684 Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup, | 1684 Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup, |
| 1685 StrictModeFlag strict_mode, | 1685 StrictModeFlag strict_mode, |
| 1686 Handle<JSObject> receiver, | 1686 Handle<JSObject> receiver, |
| 1687 Handle<String> name) { | 1687 Handle<String> name, |
| 1688 Handle<Object> value) { |
| 1688 Handle<JSObject> holder(lookup->holder()); | 1689 Handle<JSObject> holder(lookup->holder()); |
| 1689 switch (lookup->type()) { | 1690 switch (lookup->type()) { |
| 1690 case FIELD: | 1691 case FIELD: |
| 1691 return isolate()->stub_cache()->ComputeStoreField( | 1692 return isolate()->stub_cache()->ComputeStoreField( |
| 1692 name, receiver, lookup, strict_mode); | 1693 name, receiver, lookup, strict_mode); |
| 1693 case NORMAL: | 1694 case NORMAL: |
| 1694 if (receiver->IsGlobalObject()) { | 1695 if (receiver->IsGlobalObject()) { |
| 1695 // The stub generated for the global object picks the value directly | 1696 // The stub generated for the global object picks the value directly |
| 1696 // from the property cell. So the property must be directly on the | 1697 // from the property cell. So the property must be directly on the |
| 1697 // global object. | 1698 // global object. |
| 1698 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); | 1699 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); |
| 1699 Handle<PropertyCell> cell( | 1700 Handle<PropertyCell> cell( |
| 1700 global->GetPropertyCell(lookup), isolate()); | 1701 global->GetPropertyCell(lookup), isolate()); |
| 1701 return isolate()->stub_cache()->ComputeStoreGlobal( | 1702 return isolate()->stub_cache()->ComputeStoreGlobal( |
| 1702 name, global, cell, strict_mode); | 1703 name, global, cell, value, strict_mode); |
| 1703 } | 1704 } |
| 1704 ASSERT(holder.is_identical_to(receiver)); | 1705 ASSERT(holder.is_identical_to(receiver)); |
| 1705 return isolate()->stub_cache()->ComputeStoreNormal(strict_mode); | 1706 return isolate()->stub_cache()->ComputeStoreNormal(strict_mode); |
| 1706 case CALLBACKS: { | 1707 case CALLBACKS: { |
| 1707 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); | 1708 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); |
| 1708 if (callback->IsExecutableAccessorInfo()) { | 1709 if (callback->IsExecutableAccessorInfo()) { |
| 1709 Handle<ExecutableAccessorInfo> info = | 1710 Handle<ExecutableAccessorInfo> info = |
| 1710 Handle<ExecutableAccessorInfo>::cast(callback); | 1711 Handle<ExecutableAccessorInfo>::cast(callback); |
| 1711 if (v8::ToCData<Address>(info->setter()) == 0) break; | 1712 if (v8::ToCData<Address>(info->setter()) == 0) break; |
| 1712 if (!holder->HasFastProperties()) break; | 1713 if (!holder->HasFastProperties()) break; |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2086 } | 2087 } |
| 2087 | 2088 |
| 2088 return Runtime::SetObjectPropertyOrFail( | 2089 return Runtime::SetObjectPropertyOrFail( |
| 2089 isolate(), object , key, value, NONE, strict_mode); | 2090 isolate(), object , key, value, NONE, strict_mode); |
| 2090 } | 2091 } |
| 2091 | 2092 |
| 2092 | 2093 |
| 2093 Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup, | 2094 Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup, |
| 2094 StrictModeFlag strict_mode, | 2095 StrictModeFlag strict_mode, |
| 2095 Handle<JSObject> receiver, | 2096 Handle<JSObject> receiver, |
| 2096 Handle<String> name) { | 2097 Handle<String> name, |
| 2098 Handle<Object> value) { |
| 2097 // If the property has a non-field type allowing map transitions | 2099 // If the property has a non-field type allowing map transitions |
| 2098 // where there is extra room in the object, we leave the IC in its | 2100 // where there is extra room in the object, we leave the IC in its |
| 2099 // current state. | 2101 // current state. |
| 2100 switch (lookup->type()) { | 2102 switch (lookup->type()) { |
| 2101 case FIELD: | 2103 case FIELD: |
| 2102 return isolate()->stub_cache()->ComputeKeyedStoreField( | 2104 return isolate()->stub_cache()->ComputeKeyedStoreField( |
| 2103 name, receiver, lookup, strict_mode); | 2105 name, receiver, lookup, strict_mode); |
| 2104 case TRANSITION: { | 2106 case TRANSITION: { |
| 2105 // Explicitly pass in the receiver map since LookupForWrite may have | 2107 // Explicitly pass in the receiver map since LookupForWrite may have |
| 2106 // stored something else than the receiver in the holder. | 2108 // stored something else than the receiver in the holder. |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2238 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 2240 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
| 2239 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | 2241 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
| 2240 return ic.Store(state, | 2242 return ic.Store(state, |
| 2241 Code::GetStrictMode(extra_ic_state), | 2243 Code::GetStrictMode(extra_ic_state), |
| 2242 args.at<Object>(0), | 2244 args.at<Object>(0), |
| 2243 args.at<String>(1), | 2245 args.at<String>(1), |
| 2244 args.at<Object>(2)); | 2246 args.at<Object>(2)); |
| 2245 } | 2247 } |
| 2246 | 2248 |
| 2247 | 2249 |
| 2250 RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) { |
| 2251 HandleScope scope(isolate); |
| 2252 ASSERT(args.length() == 3); |
| 2253 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate); |
| 2254 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
| 2255 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
| 2256 return ic.Store(state, |
| 2257 Code::GetStrictMode(extra_ic_state), |
| 2258 args.at<Object>(0), |
| 2259 args.at<String>(1), |
| 2260 args.at<Object>(2)); |
| 2261 } |
| 2262 |
| 2263 |
| 2248 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { | 2264 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { |
| 2249 SealHandleScope shs(isolate); | 2265 SealHandleScope shs(isolate); |
| 2250 | 2266 |
| 2251 ASSERT(args.length() == 2); | 2267 ASSERT(args.length() == 2); |
| 2252 JSArray* receiver = JSArray::cast(args[0]); | 2268 JSArray* receiver = JSArray::cast(args[0]); |
| 2253 Object* len = args[1]; | 2269 Object* len = args[1]; |
| 2254 | 2270 |
| 2255 // The generated code should filter out non-Smis before we get here. | 2271 // The generated code should filter out non-Smis before we get here. |
| 2256 ASSERT(len->IsSmi()); | 2272 ASSERT(len->IsSmi()); |
| 2257 | 2273 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2394 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | 2410 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
| 2395 return ic.Store(state, | 2411 return ic.Store(state, |
| 2396 Code::GetStrictMode(extra_ic_state), | 2412 Code::GetStrictMode(extra_ic_state), |
| 2397 args.at<Object>(0), | 2413 args.at<Object>(0), |
| 2398 args.at<Object>(1), | 2414 args.at<Object>(1), |
| 2399 args.at<Object>(2), | 2415 args.at<Object>(2), |
| 2400 MISS_FORCE_GENERIC); | 2416 MISS_FORCE_GENERIC); |
| 2401 } | 2417 } |
| 2402 | 2418 |
| 2403 | 2419 |
| 2404 void UnaryOpIC::patch(Code* code) { | |
| 2405 set_target(code); | |
| 2406 } | |
| 2407 | |
| 2408 | |
| 2409 const char* UnaryOpIC::GetName(TypeInfo type_info) { | |
| 2410 switch (type_info) { | |
| 2411 case UNINITIALIZED: return "Uninitialized"; | |
| 2412 case SMI: return "Smi"; | |
| 2413 case NUMBER: return "Number"; | |
| 2414 case GENERIC: return "Generic"; | |
| 2415 default: return "Invalid"; | |
| 2416 } | |
| 2417 } | |
| 2418 | |
| 2419 | |
| 2420 UnaryOpIC::State UnaryOpIC::ToState(TypeInfo type_info) { | |
| 2421 switch (type_info) { | |
| 2422 case UNINITIALIZED: | |
| 2423 return v8::internal::UNINITIALIZED; | |
| 2424 case SMI: | |
| 2425 case NUMBER: | |
| 2426 return MONOMORPHIC; | |
| 2427 case GENERIC: | |
| 2428 return v8::internal::GENERIC; | |
| 2429 } | |
| 2430 UNREACHABLE(); | |
| 2431 return v8::internal::UNINITIALIZED; | |
| 2432 } | |
| 2433 | |
| 2434 | |
| 2435 Handle<Type> UnaryOpIC::TypeInfoToType(TypeInfo type_info, Isolate* isolate) { | |
| 2436 switch (type_info) { | |
| 2437 case UNINITIALIZED: | |
| 2438 return handle(Type::None(), isolate); | |
| 2439 case SMI: | |
| 2440 return handle(Type::Smi(), isolate); | |
| 2441 case NUMBER: | |
| 2442 return handle(Type::Number(), isolate); | |
| 2443 case GENERIC: | |
| 2444 return handle(Type::Any(), isolate); | |
| 2445 } | |
| 2446 UNREACHABLE(); | |
| 2447 return handle(Type::Any(), isolate); | |
| 2448 } | |
| 2449 | |
| 2450 | |
| 2451 UnaryOpIC::TypeInfo UnaryOpIC::GetTypeInfo(Handle<Object> operand) { | |
| 2452 v8::internal::TypeInfo operand_type = | |
| 2453 v8::internal::TypeInfo::FromValue(operand); | |
| 2454 if (operand_type.IsSmi()) { | |
| 2455 return SMI; | |
| 2456 } else if (operand_type.IsNumber()) { | |
| 2457 return NUMBER; | |
| 2458 } else { | |
| 2459 return GENERIC; | |
| 2460 } | |
| 2461 } | |
| 2462 | |
| 2463 | |
| 2464 UnaryOpIC::TypeInfo UnaryOpIC::ComputeNewType( | |
| 2465 TypeInfo current_type, | |
| 2466 TypeInfo previous_type) { | |
| 2467 switch (previous_type) { | |
| 2468 case UNINITIALIZED: | |
| 2469 return current_type; | |
| 2470 case SMI: | |
| 2471 return (current_type == GENERIC) ? GENERIC : NUMBER; | |
| 2472 case NUMBER: | |
| 2473 return GENERIC; | |
| 2474 case GENERIC: | |
| 2475 // We should never do patching if we are in GENERIC state. | |
| 2476 UNREACHABLE(); | |
| 2477 return GENERIC; | |
| 2478 } | |
| 2479 UNREACHABLE(); | |
| 2480 return GENERIC; | |
| 2481 } | |
| 2482 | |
| 2483 | |
| 2484 void BinaryOpIC::patch(Code* code) { | 2420 void BinaryOpIC::patch(Code* code) { |
| 2485 set_target(code); | 2421 set_target(code); |
| 2486 } | 2422 } |
| 2487 | 2423 |
| 2488 | 2424 |
| 2489 const char* BinaryOpIC::GetName(TypeInfo type_info) { | 2425 const char* BinaryOpIC::GetName(TypeInfo type_info) { |
| 2490 switch (type_info) { | 2426 switch (type_info) { |
| 2491 case UNINITIALIZED: return "Uninitialized"; | 2427 case UNINITIALIZED: return "Uninitialized"; |
| 2492 case SMI: return "Smi"; | 2428 case SMI: return "Smi"; |
| 2493 case INT32: return "Int32"; | 2429 case INT32: return "Int32"; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2551 Isolate* isolate) { | 2487 Isolate* isolate) { |
| 2552 TypeInfo left_typeinfo, right_typeinfo, result_typeinfo; | 2488 TypeInfo left_typeinfo, right_typeinfo, result_typeinfo; |
| 2553 BinaryOpStub::decode_types_from_minor_key( | 2489 BinaryOpStub::decode_types_from_minor_key( |
| 2554 minor_key, &left_typeinfo, &right_typeinfo, &result_typeinfo); | 2490 minor_key, &left_typeinfo, &right_typeinfo, &result_typeinfo); |
| 2555 *left = TypeInfoToType(left_typeinfo, isolate); | 2491 *left = TypeInfoToType(left_typeinfo, isolate); |
| 2556 *right = TypeInfoToType(right_typeinfo, isolate); | 2492 *right = TypeInfoToType(right_typeinfo, isolate); |
| 2557 *result = TypeInfoToType(result_typeinfo, isolate); | 2493 *result = TypeInfoToType(result_typeinfo, isolate); |
| 2558 } | 2494 } |
| 2559 | 2495 |
| 2560 | 2496 |
| 2561 RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) { | 2497 MaybeObject* UnaryOpIC::Transition(Handle<Object> object) { |
| 2562 ASSERT(args.length() == 4); | 2498 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); |
| 2499 UnaryOpStub stub(extra_ic_state); |
| 2563 | 2500 |
| 2564 HandleScope scope(isolate); | 2501 stub.UpdateStatus(object); |
| 2565 Handle<Object> operand = args.at<Object>(0); | |
| 2566 Token::Value op = static_cast<Token::Value>(args.smi_at(1)); | |
| 2567 UnaryOverwriteMode mode = static_cast<UnaryOverwriteMode>(args.smi_at(2)); | |
| 2568 UnaryOpIC::TypeInfo previous_type = | |
| 2569 static_cast<UnaryOpIC::TypeInfo>(args.smi_at(3)); | |
| 2570 | 2502 |
| 2571 UnaryOpIC::TypeInfo type = UnaryOpIC::GetTypeInfo(operand); | 2503 Handle<Code> code = stub.GetCode(isolate()); |
| 2572 type = UnaryOpIC::ComputeNewType(type, previous_type); | 2504 set_target(*code); |
| 2573 | 2505 |
| 2574 UnaryOpStub stub(op, mode, type); | 2506 return stub.Result(object, isolate()); |
| 2575 Handle<Code> code = stub.GetCode(isolate); | |
| 2576 if (!code.is_null()) { | |
| 2577 if (FLAG_trace_ic) { | |
| 2578 PrintF("[UnaryOpIC in "); | |
| 2579 JavaScriptFrame::PrintTop(isolate, stdout, false, true); | |
| 2580 PrintF(" %s => %s #%s @ %p]\n", | |
| 2581 UnaryOpIC::GetName(previous_type), | |
| 2582 UnaryOpIC::GetName(type), | |
| 2583 Token::Name(op), | |
| 2584 static_cast<void*>(*code)); | |
| 2585 } | |
| 2586 UnaryOpIC ic(isolate); | |
| 2587 ic.patch(*code); | |
| 2588 } | |
| 2589 | |
| 2590 Handle<JSBuiltinsObject> builtins(isolate->js_builtins_object()); | |
| 2591 Object* builtin = NULL; // Initialization calms down the compiler. | |
| 2592 switch (op) { | |
| 2593 case Token::SUB: | |
| 2594 builtin = builtins->javascript_builtin(Builtins::UNARY_MINUS); | |
| 2595 break; | |
| 2596 case Token::BIT_NOT: | |
| 2597 builtin = builtins->javascript_builtin(Builtins::BIT_NOT); | |
| 2598 break; | |
| 2599 default: | |
| 2600 UNREACHABLE(); | |
| 2601 } | |
| 2602 | |
| 2603 Handle<JSFunction> builtin_function(JSFunction::cast(builtin), isolate); | |
| 2604 | |
| 2605 bool caught_exception; | |
| 2606 Handle<Object> result = Execution::Call(builtin_function, operand, 0, NULL, | |
| 2607 &caught_exception); | |
| 2608 if (caught_exception) { | |
| 2609 return Failure::Exception(); | |
| 2610 } | |
| 2611 return *result; | |
| 2612 } | 2507 } |
| 2613 | 2508 |
| 2614 | 2509 |
| 2510 RUNTIME_FUNCTION(MaybeObject*, UnaryOpIC_Miss) { |
| 2511 HandleScope scope(isolate); |
| 2512 Handle<Object> object = args.at<Object>(0); |
| 2513 UnaryOpIC ic(isolate); |
| 2514 return ic.Transition(object); |
| 2515 } |
| 2516 |
| 2517 |
| 2615 static BinaryOpIC::TypeInfo TypeInfoFromValue(Handle<Object> value, | 2518 static BinaryOpIC::TypeInfo TypeInfoFromValue(Handle<Object> value, |
| 2616 Token::Value op) { | 2519 Token::Value op) { |
| 2617 v8::internal::TypeInfo type = v8::internal::TypeInfo::FromValue(value); | 2520 v8::internal::TypeInfo type = v8::internal::TypeInfo::FromValue(value); |
| 2618 if (type.IsSmi()) return BinaryOpIC::SMI; | 2521 if (type.IsSmi()) return BinaryOpIC::SMI; |
| 2619 if (type.IsInteger32()) { | 2522 if (type.IsInteger32()) { |
| 2620 if (kSmiValueSize == 32) return BinaryOpIC::SMI; | 2523 if (kSmiValueSize == 32) return BinaryOpIC::SMI; |
| 2621 return BinaryOpIC::INT32; | 2524 return BinaryOpIC::INT32; |
| 2622 } | 2525 } |
| 2623 if (type.IsNumber()) return BinaryOpIC::NUMBER; | 2526 if (type.IsNumber()) return BinaryOpIC::NUMBER; |
| 2624 if (type.IsString()) return BinaryOpIC::STRING; | 2527 if (type.IsString()) return BinaryOpIC::STRING; |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3062 | 2965 |
| 3063 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { | 2966 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { |
| 3064 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); | 2967 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); |
| 3065 | 2968 |
| 3066 CompareNilICStub stub(extra_ic_state); | 2969 CompareNilICStub stub(extra_ic_state); |
| 3067 | 2970 |
| 3068 // Extract the current supported types from the patched IC and calculate what | 2971 // Extract the current supported types from the patched IC and calculate what |
| 3069 // types must be supported as a result of the miss. | 2972 // types must be supported as a result of the miss. |
| 3070 bool already_monomorphic = stub.IsMonomorphic(); | 2973 bool already_monomorphic = stub.IsMonomorphic(); |
| 3071 | 2974 |
| 3072 CompareNilICStub::State old_state = stub.GetState(); | 2975 stub.UpdateStatus(object); |
| 3073 stub.Record(object); | |
| 3074 old_state.TraceTransition(stub.GetState()); | |
| 3075 | 2976 |
| 3076 NilValue nil = stub.GetNilValue(); | 2977 NilValue nil = stub.GetNilValue(); |
| 3077 | 2978 |
| 3078 // Find or create the specialized stub to support the new set of types. | 2979 // Find or create the specialized stub to support the new set of types. |
| 3079 Handle<Code> code; | 2980 Handle<Code> code; |
| 3080 if (stub.IsMonomorphic()) { | 2981 if (stub.IsMonomorphic()) { |
| 3081 Handle<Map> monomorphic_map(already_monomorphic | 2982 Handle<Map> monomorphic_map(already_monomorphic |
| 3082 ? target()->FindFirstMap() | 2983 ? target()->FindFirstMap() |
| 3083 : HeapObject::cast(*object)->map()); | 2984 : HeapObject::cast(*object)->map()); |
| 3084 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub); | 2985 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3101 RUNTIME_FUNCTION(MaybeObject*, Unreachable) { | 3002 RUNTIME_FUNCTION(MaybeObject*, Unreachable) { |
| 3102 UNREACHABLE(); | 3003 UNREACHABLE(); |
| 3103 CHECK(false); | 3004 CHECK(false); |
| 3104 return isolate->heap()->undefined_value(); | 3005 return isolate->heap()->undefined_value(); |
| 3105 } | 3006 } |
| 3106 | 3007 |
| 3107 | 3008 |
| 3108 MaybeObject* ToBooleanIC::ToBoolean(Handle<Object> object, | 3009 MaybeObject* ToBooleanIC::ToBoolean(Handle<Object> object, |
| 3109 Code::ExtraICState extra_ic_state) { | 3010 Code::ExtraICState extra_ic_state) { |
| 3110 ToBooleanStub stub(extra_ic_state); | 3011 ToBooleanStub stub(extra_ic_state); |
| 3111 bool to_boolean_value = stub.Record(object); | 3012 bool to_boolean_value = stub.UpdateStatus(object); |
| 3112 Handle<Code> code = stub.GetCode(isolate()); | 3013 Handle<Code> code = stub.GetCode(isolate()); |
| 3113 set_target(*code); | 3014 set_target(*code); |
| 3114 return Smi::FromInt(to_boolean_value ? 1 : 0); | 3015 return Smi::FromInt(to_boolean_value ? 1 : 0); |
| 3115 } | 3016 } |
| 3116 | 3017 |
| 3117 | 3018 |
| 3118 RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss) { | 3019 RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss) { |
| 3119 ASSERT(args.length() == 1); | 3020 ASSERT(args.length() == 1); |
| 3120 HandleScope scope(isolate); | 3021 HandleScope scope(isolate); |
| 3121 Handle<Object> object = args.at<Object>(0); | 3022 Handle<Object> object = args.at<Object>(0); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3132 #undef ADDR | 3033 #undef ADDR |
| 3133 }; | 3034 }; |
| 3134 | 3035 |
| 3135 | 3036 |
| 3136 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3037 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 3137 return IC_utilities[id]; | 3038 return IC_utilities[id]; |
| 3138 } | 3039 } |
| 3139 | 3040 |
| 3140 | 3041 |
| 3141 } } // namespace v8::internal | 3042 } } // namespace v8::internal |
| OLD | NEW |