| 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 2383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2394 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | 2394 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
| 2395 return ic.Store(state, | 2395 return ic.Store(state, |
| 2396 Code::GetStrictMode(extra_ic_state), | 2396 Code::GetStrictMode(extra_ic_state), |
| 2397 args.at<Object>(0), | 2397 args.at<Object>(0), |
| 2398 args.at<Object>(1), | 2398 args.at<Object>(1), |
| 2399 args.at<Object>(2), | 2399 args.at<Object>(2), |
| 2400 MISS_FORCE_GENERIC); | 2400 MISS_FORCE_GENERIC); |
| 2401 } | 2401 } |
| 2402 | 2402 |
| 2403 | 2403 |
| 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 |
| 2404 void BinaryOpIC::patch(Code* code) { | 2484 void BinaryOpIC::patch(Code* code) { |
| 2405 set_target(code); | 2485 set_target(code); |
| 2406 } | 2486 } |
| 2407 | 2487 |
| 2408 | 2488 |
| 2409 const char* BinaryOpIC::GetName(TypeInfo type_info) { | 2489 const char* BinaryOpIC::GetName(TypeInfo type_info) { |
| 2410 switch (type_info) { | 2490 switch (type_info) { |
| 2411 case UNINITIALIZED: return "Uninitialized"; | 2491 case UNINITIALIZED: return "Uninitialized"; |
| 2412 case SMI: return "Smi"; | 2492 case SMI: return "Smi"; |
| 2413 case INT32: return "Int32"; | 2493 case INT32: return "Int32"; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2471 Isolate* isolate) { | 2551 Isolate* isolate) { |
| 2472 TypeInfo left_typeinfo, right_typeinfo, result_typeinfo; | 2552 TypeInfo left_typeinfo, right_typeinfo, result_typeinfo; |
| 2473 BinaryOpStub::decode_types_from_minor_key( | 2553 BinaryOpStub::decode_types_from_minor_key( |
| 2474 minor_key, &left_typeinfo, &right_typeinfo, &result_typeinfo); | 2554 minor_key, &left_typeinfo, &right_typeinfo, &result_typeinfo); |
| 2475 *left = TypeInfoToType(left_typeinfo, isolate); | 2555 *left = TypeInfoToType(left_typeinfo, isolate); |
| 2476 *right = TypeInfoToType(right_typeinfo, isolate); | 2556 *right = TypeInfoToType(right_typeinfo, isolate); |
| 2477 *result = TypeInfoToType(result_typeinfo, isolate); | 2557 *result = TypeInfoToType(result_typeinfo, isolate); |
| 2478 } | 2558 } |
| 2479 | 2559 |
| 2480 | 2560 |
| 2481 MaybeObject* UnaryOpIC::Transition(Handle<Object> object) { | 2561 RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) { |
| 2482 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); | 2562 ASSERT(args.length() == 4); |
| 2483 UnaryOpStub stub(extra_ic_state); | |
| 2484 | 2563 |
| 2485 stub.UpdateStatus(object); | 2564 HandleScope scope(isolate); |
| 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)); |
| 2486 | 2570 |
| 2487 Handle<Code> code = stub.GetCode(isolate()); | 2571 UnaryOpIC::TypeInfo type = UnaryOpIC::GetTypeInfo(operand); |
| 2488 set_target(*code); | 2572 type = UnaryOpIC::ComputeNewType(type, previous_type); |
| 2489 | 2573 |
| 2490 return stub.Result(object, isolate()); | 2574 UnaryOpStub stub(op, mode, type); |
| 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; |
| 2491 } | 2612 } |
| 2492 | 2613 |
| 2493 | 2614 |
| 2494 RUNTIME_FUNCTION(MaybeObject*, UnaryOpIC_Miss) { | |
| 2495 HandleScope scope(isolate); | |
| 2496 Handle<Object> object = args.at<Object>(0); | |
| 2497 UnaryOpIC ic(isolate); | |
| 2498 return ic.Transition(object); | |
| 2499 } | |
| 2500 | |
| 2501 | |
| 2502 static BinaryOpIC::TypeInfo TypeInfoFromValue(Handle<Object> value, | 2615 static BinaryOpIC::TypeInfo TypeInfoFromValue(Handle<Object> value, |
| 2503 Token::Value op) { | 2616 Token::Value op) { |
| 2504 v8::internal::TypeInfo type = v8::internal::TypeInfo::FromValue(value); | 2617 v8::internal::TypeInfo type = v8::internal::TypeInfo::FromValue(value); |
| 2505 if (type.IsSmi()) return BinaryOpIC::SMI; | 2618 if (type.IsSmi()) return BinaryOpIC::SMI; |
| 2506 if (type.IsInteger32()) { | 2619 if (type.IsInteger32()) { |
| 2507 if (kSmiValueSize == 32) return BinaryOpIC::SMI; | 2620 if (kSmiValueSize == 32) return BinaryOpIC::SMI; |
| 2508 return BinaryOpIC::INT32; | 2621 return BinaryOpIC::INT32; |
| 2509 } | 2622 } |
| 2510 if (type.IsNumber()) return BinaryOpIC::NUMBER; | 2623 if (type.IsNumber()) return BinaryOpIC::NUMBER; |
| 2511 if (type.IsString()) return BinaryOpIC::STRING; | 2624 if (type.IsString()) return BinaryOpIC::STRING; |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2949 | 3062 |
| 2950 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { | 3063 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { |
| 2951 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); | 3064 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); |
| 2952 | 3065 |
| 2953 CompareNilICStub stub(extra_ic_state); | 3066 CompareNilICStub stub(extra_ic_state); |
| 2954 | 3067 |
| 2955 // Extract the current supported types from the patched IC and calculate what | 3068 // Extract the current supported types from the patched IC and calculate what |
| 2956 // types must be supported as a result of the miss. | 3069 // types must be supported as a result of the miss. |
| 2957 bool already_monomorphic = stub.IsMonomorphic(); | 3070 bool already_monomorphic = stub.IsMonomorphic(); |
| 2958 | 3071 |
| 2959 stub.UpdateStatus(object); | 3072 CompareNilICStub::State old_state = stub.GetState(); |
| 3073 stub.Record(object); |
| 3074 old_state.TraceTransition(stub.GetState()); |
| 2960 | 3075 |
| 2961 NilValue nil = stub.GetNilValue(); | 3076 NilValue nil = stub.GetNilValue(); |
| 2962 | 3077 |
| 2963 // Find or create the specialized stub to support the new set of types. | 3078 // Find or create the specialized stub to support the new set of types. |
| 2964 Handle<Code> code; | 3079 Handle<Code> code; |
| 2965 if (stub.IsMonomorphic()) { | 3080 if (stub.IsMonomorphic()) { |
| 2966 Handle<Map> monomorphic_map(already_monomorphic | 3081 Handle<Map> monomorphic_map(already_monomorphic |
| 2967 ? target()->FindFirstMap() | 3082 ? target()->FindFirstMap() |
| 2968 : HeapObject::cast(*object)->map()); | 3083 : HeapObject::cast(*object)->map()); |
| 2969 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub); | 3084 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2986 RUNTIME_FUNCTION(MaybeObject*, Unreachable) { | 3101 RUNTIME_FUNCTION(MaybeObject*, Unreachable) { |
| 2987 UNREACHABLE(); | 3102 UNREACHABLE(); |
| 2988 CHECK(false); | 3103 CHECK(false); |
| 2989 return isolate->heap()->undefined_value(); | 3104 return isolate->heap()->undefined_value(); |
| 2990 } | 3105 } |
| 2991 | 3106 |
| 2992 | 3107 |
| 2993 MaybeObject* ToBooleanIC::ToBoolean(Handle<Object> object, | 3108 MaybeObject* ToBooleanIC::ToBoolean(Handle<Object> object, |
| 2994 Code::ExtraICState extra_ic_state) { | 3109 Code::ExtraICState extra_ic_state) { |
| 2995 ToBooleanStub stub(extra_ic_state); | 3110 ToBooleanStub stub(extra_ic_state); |
| 2996 bool to_boolean_value = stub.UpdateStatus(object); | 3111 bool to_boolean_value = stub.Record(object); |
| 2997 Handle<Code> code = stub.GetCode(isolate()); | 3112 Handle<Code> code = stub.GetCode(isolate()); |
| 2998 set_target(*code); | 3113 set_target(*code); |
| 2999 return Smi::FromInt(to_boolean_value ? 1 : 0); | 3114 return Smi::FromInt(to_boolean_value ? 1 : 0); |
| 3000 } | 3115 } |
| 3001 | 3116 |
| 3002 | 3117 |
| 3003 RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss) { | 3118 RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss) { |
| 3004 ASSERT(args.length() == 1); | 3119 ASSERT(args.length() == 1); |
| 3005 HandleScope scope(isolate); | 3120 HandleScope scope(isolate); |
| 3006 Handle<Object> object = args.at<Object>(0); | 3121 Handle<Object> object = args.at<Object>(0); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3017 #undef ADDR | 3132 #undef ADDR |
| 3018 }; | 3133 }; |
| 3019 | 3134 |
| 3020 | 3135 |
| 3021 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3136 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 3022 return IC_utilities[id]; | 3137 return IC_utilities[id]; |
| 3023 } | 3138 } |
| 3024 | 3139 |
| 3025 | 3140 |
| 3026 } } // namespace v8::internal | 3141 } } // namespace v8::internal |
| OLD | NEW |