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::Integer31(), 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) { | 2404 void BinaryOpIC::patch(Code* code) { |
2485 set_target(code); | 2405 set_target(code); |
2486 } | 2406 } |
2487 | 2407 |
2488 | 2408 |
2489 const char* BinaryOpIC::GetName(TypeInfo type_info) { | 2409 const char* BinaryOpIC::GetName(TypeInfo type_info) { |
2490 switch (type_info) { | 2410 switch (type_info) { |
2491 case UNINITIALIZED: return "Uninitialized"; | 2411 case UNINITIALIZED: return "Uninitialized"; |
2492 case SMI: return "Smi"; | 2412 case SMI: return "Smi"; |
2493 case INT32: return "Int32"; | 2413 case INT32: return "Int32"; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2549 Handle<Type>* right, | 2469 Handle<Type>* right, |
2550 Handle<Type>* result, | 2470 Handle<Type>* result, |
2551 Isolate* isolate) { | 2471 Isolate* isolate) { |
2552 TypeInfo left_typeinfo, right_typeinfo, result_typeinfo; | 2472 TypeInfo left_typeinfo, right_typeinfo, result_typeinfo; |
2553 BinaryOpStub::decode_types_from_minor_key( | 2473 BinaryOpStub::decode_types_from_minor_key( |
2554 minor_key, &left_typeinfo, &right_typeinfo, &result_typeinfo); | 2474 minor_key, &left_typeinfo, &right_typeinfo, &result_typeinfo); |
2555 *left = TypeInfoToType(left_typeinfo, isolate); | 2475 *left = TypeInfoToType(left_typeinfo, isolate); |
2556 *right = TypeInfoToType(right_typeinfo, isolate); | 2476 *right = TypeInfoToType(right_typeinfo, isolate); |
2557 *result = TypeInfoToType(result_typeinfo, isolate); | 2477 *result = TypeInfoToType(result_typeinfo, isolate); |
2558 } | 2478 } |
2559 | 2479 |
danno
2013/06/21 16:38:04
nit: two lines between functions
| |
2480 MaybeObject* UnaryOpIC::Transition(Handle<Object> object) { | |
2481 Code::ExtraICState extra_ic_state = target()->extra_ic_state(); | |
2482 UnaryOpStub stub(extra_ic_state); | |
2560 | 2483 |
2561 RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) { | 2484 stub.Record(object); |
danno
2013/06/21 16:38:04
Can you change "Record" here and elsewhere to Upda
| |
2562 ASSERT(args.length() == 4); | |
2563 | 2485 |
2564 HandleScope scope(isolate); | 2486 Handle<Code> code = stub.GetCode(isolate()); |
2565 Handle<Object> operand = args.at<Object>(0); | 2487 set_target(*code); |
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 | 2488 |
2571 UnaryOpIC::TypeInfo type = UnaryOpIC::GetTypeInfo(operand); | 2489 return stub.Result(object, isolate()); |
2572 type = UnaryOpIC::ComputeNewType(type, previous_type); | |
2573 | |
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; | |
2612 } | 2490 } |
2613 | 2491 |
2614 | 2492 |
2493 RUNTIME_FUNCTION(MaybeObject*, UnaryOpIC_Miss) { | |
2494 HandleScope scope(isolate); | |
2495 Handle<Object> object = args.at<Object>(0); | |
2496 UnaryOpIC ic(isolate); | |
2497 return ic.Transition(object); | |
2498 } | |
2499 | |
2500 | |
2615 static BinaryOpIC::TypeInfo TypeInfoFromValue(Handle<Object> value, | 2501 static BinaryOpIC::TypeInfo TypeInfoFromValue(Handle<Object> value, |
2616 Token::Value op) { | 2502 Token::Value op) { |
2617 v8::internal::TypeInfo type = v8::internal::TypeInfo::FromValue(value); | 2503 v8::internal::TypeInfo type = v8::internal::TypeInfo::FromValue(value); |
2618 if (type.IsSmi()) return BinaryOpIC::SMI; | 2504 if (type.IsSmi()) return BinaryOpIC::SMI; |
2619 if (type.IsInteger32()) { | 2505 if (type.IsInteger32()) { |
2620 if (kSmiValueSize == 32) return BinaryOpIC::SMI; | 2506 if (kSmiValueSize == 32) return BinaryOpIC::SMI; |
2621 return BinaryOpIC::INT32; | 2507 return BinaryOpIC::INT32; |
2622 } | 2508 } |
2623 if (type.IsNumber()) return BinaryOpIC::NUMBER; | 2509 if (type.IsNumber()) return BinaryOpIC::NUMBER; |
2624 if (type.IsString()) return BinaryOpIC::STRING; | 2510 if (type.IsString()) return BinaryOpIC::STRING; |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3066 | 2952 |
3067 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { | 2953 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { |
3068 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); | 2954 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); |
3069 | 2955 |
3070 CompareNilICStub stub(extra_ic_state); | 2956 CompareNilICStub stub(extra_ic_state); |
3071 | 2957 |
3072 // Extract the current supported types from the patched IC and calculate what | 2958 // Extract the current supported types from the patched IC and calculate what |
3073 // types must be supported as a result of the miss. | 2959 // types must be supported as a result of the miss. |
3074 bool already_monomorphic = stub.IsMonomorphic(); | 2960 bool already_monomorphic = stub.IsMonomorphic(); |
3075 | 2961 |
3076 CompareNilICStub::State old_state = stub.GetState(); | |
3077 stub.Record(object); | 2962 stub.Record(object); |
3078 old_state.TraceTransition(stub.GetState()); | |
3079 | 2963 |
3080 NilValue nil = stub.GetNilValue(); | 2964 NilValue nil = stub.GetNilValue(); |
3081 | 2965 |
3082 // Find or create the specialized stub to support the new set of types. | 2966 // Find or create the specialized stub to support the new set of types. |
3083 Handle<Code> code; | 2967 Handle<Code> code; |
3084 if (stub.IsMonomorphic()) { | 2968 if (stub.IsMonomorphic()) { |
3085 Handle<Map> monomorphic_map(already_monomorphic | 2969 Handle<Map> monomorphic_map(already_monomorphic |
3086 ? target()->FindFirstMap() | 2970 ? target()->FindFirstMap() |
3087 : HeapObject::cast(*object)->map()); | 2971 : HeapObject::cast(*object)->map()); |
3088 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub); | 2972 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3136 #undef ADDR | 3020 #undef ADDR |
3137 }; | 3021 }; |
3138 | 3022 |
3139 | 3023 |
3140 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3024 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
3141 return IC_utilities[id]; | 3025 return IC_utilities[id]; |
3142 } | 3026 } |
3143 | 3027 |
3144 | 3028 |
3145 } } // namespace v8::internal | 3029 } } // namespace v8::internal |
OLD | NEW |