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 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1208 if (to_ == JS_FUNCTION_TYPE) stream->Add(" function"); | 1208 if (to_ == JS_FUNCTION_TYPE) stream->Add(" function"); |
1209 break; | 1209 break; |
1210 default: | 1210 default: |
1211 break; | 1211 break; |
1212 } | 1212 } |
1213 } | 1213 } |
1214 | 1214 |
1215 | 1215 |
1216 void HTypeofIsAndBranch::PrintDataTo(StringStream* stream) { | 1216 void HTypeofIsAndBranch::PrintDataTo(StringStream* stream) { |
1217 value()->PrintNameTo(stream); | 1217 value()->PrintNameTo(stream); |
1218 stream->Add(" == %o", *type_literal_); | 1218 stream->Add(" == %o", *type_literal_.handle()); |
1219 HControlInstruction::PrintDataTo(stream); | 1219 HControlInstruction::PrintDataTo(stream); |
1220 } | 1220 } |
1221 | 1221 |
1222 | 1222 |
1223 static String* TypeOfString(HConstant* constant, Isolate* isolate) { | |
1224 Heap* heap = isolate->heap(); | |
1225 if (constant->HasNumberValue()) return heap->number_string(); | |
1226 if (constant->IsUndetectable()) return heap->undefined_string(); | |
1227 if (constant->HasStringValue()) return heap->string_string(); | |
1228 switch (constant->GetInstanceType()) { | |
1229 case ODDBALL_TYPE: { | |
1230 Unique<Object> unique = constant->GetUnique(); | |
1231 if (unique.IsKnownGlobal(heap->true_value()) || | |
1232 unique.IsKnownGlobal(heap->false_value())) { | |
1233 return heap->boolean_string(); | |
1234 } | |
1235 if (unique.IsKnownGlobal(heap->null_value())) { | |
1236 return FLAG_harmony_typeof ? heap->null_string() | |
1237 : heap->object_string(); | |
1238 } | |
1239 ASSERT(unique.IsKnownGlobal(heap->undefined_value())); | |
1240 return heap->undefined_string(); | |
1241 } | |
1242 case SYMBOL_TYPE: | |
1243 return heap->symbol_string(); | |
1244 case JS_FUNCTION_TYPE: | |
1245 case JS_FUNCTION_PROXY_TYPE: | |
1246 return heap->function_string(); | |
1247 default: | |
1248 return heap->object_string(); | |
1249 } | |
1250 } | |
1251 | |
1252 | |
1223 bool HTypeofIsAndBranch::KnownSuccessorBlock(HBasicBlock** block) { | 1253 bool HTypeofIsAndBranch::KnownSuccessorBlock(HBasicBlock** block) { |
1224 if (value()->representation().IsSpecialization()) { | 1254 if (FLAG_fold_constants && value()->IsConstant()) { |
1225 if (compares_number_type()) { | 1255 HConstant* constant = HConstant::cast(value()); |
1226 *block = FirstSuccessor(); | 1256 String* type_string = TypeOfString(constant, isolate()); |
1227 } else { | 1257 bool same_type = type_literal_.IsKnownGlobal(type_string); |
1228 *block = SecondSuccessor(); | 1258 *block = same_type ? FirstSuccessor() : SecondSuccessor(); |
1229 } | 1259 return true; |
1260 } else if (value()->representation().IsSpecialization()) { | |
1261 bool number_type = | |
1262 type_literal_.IsKnownGlobal(isolate()->heap()->number_string()); | |
1263 *block = number_type ? FirstSuccessor() : SecondSuccessor(); | |
1230 return true; | 1264 return true; |
1231 } | 1265 } |
1232 *block = NULL; | 1266 *block = NULL; |
1233 return false; | 1267 return false; |
1234 } | 1268 } |
1235 | 1269 |
1236 | 1270 |
1237 void HCheckMapValue::PrintDataTo(StringStream* stream) { | 1271 void HCheckMapValue::PrintDataTo(StringStream* stream) { |
1238 value()->PrintNameTo(stream); | 1272 value()->PrintNameTo(stream); |
1239 stream->Add(" "); | 1273 stream->Add(" "); |
(...skipping 1253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2493 } | 2527 } |
2494 | 2528 |
2495 | 2529 |
2496 HConstant::HConstant(Handle<Object> handle, Representation r) | 2530 HConstant::HConstant(Handle<Object> handle, Representation r) |
2497 : HTemplateInstruction<0>(HType::TypeFromValue(handle)), | 2531 : HTemplateInstruction<0>(HType::TypeFromValue(handle)), |
2498 object_(Unique<Object>::CreateUninitialized(handle)), | 2532 object_(Unique<Object>::CreateUninitialized(handle)), |
2499 has_smi_value_(false), | 2533 has_smi_value_(false), |
2500 has_int32_value_(false), | 2534 has_int32_value_(false), |
2501 has_double_value_(false), | 2535 has_double_value_(false), |
2502 has_external_reference_value_(false), | 2536 has_external_reference_value_(false), |
2503 is_internalized_string_(false), | |
2504 is_not_in_new_space_(true), | 2537 is_not_in_new_space_(true), |
2505 is_cell_(false), | 2538 boolean_value_(handle->BooleanValue()), |
2506 boolean_value_(handle->BooleanValue()) { | 2539 is_undetectable_(false), |
2540 instance_type_(kUnknownInstanceType) { | |
2507 if (handle->IsHeapObject()) { | 2541 if (handle->IsHeapObject()) { |
2508 Heap* heap = Handle<HeapObject>::cast(handle)->GetHeap(); | 2542 Handle<HeapObject> heap_obj = Handle<HeapObject>::cast(handle); |
2543 Heap* heap = heap_obj->GetHeap(); | |
2509 is_not_in_new_space_ = !heap->InNewSpace(*handle); | 2544 is_not_in_new_space_ = !heap->InNewSpace(*handle); |
2545 instance_type_ = heap_obj->map()->instance_type(); | |
2546 is_undetectable_ = heap_obj->map()->is_undetectable(); | |
2510 } | 2547 } |
2511 if (handle->IsNumber()) { | 2548 if (handle->IsNumber()) { |
2512 double n = handle->Number(); | 2549 double n = handle->Number(); |
2513 has_int32_value_ = IsInteger32(n); | 2550 has_int32_value_ = IsInteger32(n); |
2514 int32_value_ = DoubleToInt32(n); | 2551 int32_value_ = DoubleToInt32(n); |
2515 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); | 2552 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); |
2516 double_value_ = n; | 2553 double_value_ = n; |
2517 has_double_value_ = true; | 2554 has_double_value_ = true; |
2518 // TODO(titzer): if this heap number is new space, tenure a new one. | 2555 // TODO(titzer): if this heap number is new space, tenure a new one. |
2519 } else { | |
2520 is_internalized_string_ = handle->IsInternalizedString(); | |
2521 } | 2556 } |
2522 | 2557 |
2523 is_cell_ = !handle.is_null() && | |
2524 (handle->IsCell() || handle->IsPropertyCell()); | |
2525 Initialize(r); | 2558 Initialize(r); |
2526 } | 2559 } |
2527 | 2560 |
2528 | 2561 |
2529 HConstant::HConstant(Unique<Object> unique, | 2562 HConstant::HConstant(Unique<Object> unique, |
2530 Representation r, | 2563 Representation r, |
2531 HType type, | 2564 HType type, |
2532 bool is_internalize_string, | |
2533 bool is_not_in_new_space, | 2565 bool is_not_in_new_space, |
2534 bool is_cell, | 2566 bool boolean_value, |
2535 bool boolean_value) | 2567 bool is_undetectable, |
2568 InstanceType instance_type) | |
2536 : HTemplateInstruction<0>(type), | 2569 : HTemplateInstruction<0>(type), |
2537 object_(unique), | 2570 object_(unique), |
2538 has_smi_value_(false), | 2571 has_smi_value_(false), |
2539 has_int32_value_(false), | 2572 has_int32_value_(false), |
2540 has_double_value_(false), | 2573 has_double_value_(false), |
2541 has_external_reference_value_(false), | 2574 has_external_reference_value_(false), |
2542 is_internalized_string_(is_internalize_string), | |
2543 is_not_in_new_space_(is_not_in_new_space), | 2575 is_not_in_new_space_(is_not_in_new_space), |
2544 is_cell_(is_cell), | 2576 boolean_value_(boolean_value), |
2545 boolean_value_(boolean_value) { | 2577 is_undetectable_(is_undetectable), |
2578 instance_type_(instance_type) { | |
2546 ASSERT(!unique.handle().is_null()); | 2579 ASSERT(!unique.handle().is_null()); |
2547 ASSERT(!type.IsTaggedNumber()); | 2580 ASSERT(!type.IsTaggedNumber()); |
2548 Initialize(r); | 2581 Initialize(r); |
2549 } | 2582 } |
2550 | 2583 |
2551 | 2584 |
2552 HConstant::HConstant(int32_t integer_value, | 2585 HConstant::HConstant(int32_t integer_value, |
2553 Representation r, | 2586 Representation r, |
2554 bool is_not_in_new_space, | 2587 bool is_not_in_new_space, |
2555 Unique<Object> object) | 2588 Unique<Object> object) |
2556 : object_(object), | 2589 : object_(object), |
2557 has_smi_value_(Smi::IsValid(integer_value)), | 2590 has_smi_value_(Smi::IsValid(integer_value)), |
2558 has_int32_value_(true), | 2591 has_int32_value_(true), |
2559 has_double_value_(true), | 2592 has_double_value_(true), |
2560 has_external_reference_value_(false), | 2593 has_external_reference_value_(false), |
2561 is_internalized_string_(false), | |
2562 is_not_in_new_space_(is_not_in_new_space), | 2594 is_not_in_new_space_(is_not_in_new_space), |
2563 is_cell_(false), | |
2564 boolean_value_(integer_value != 0), | 2595 boolean_value_(integer_value != 0), |
2596 is_undetectable_(false), | |
2565 int32_value_(integer_value), | 2597 int32_value_(integer_value), |
2566 double_value_(FastI2D(integer_value)) { | 2598 double_value_(FastI2D(integer_value)), |
2599 instance_type_(kUnknownInstanceType) { | |
2567 set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber()); | 2600 set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber()); |
2568 Initialize(r); | 2601 Initialize(r); |
2569 } | 2602 } |
2570 | 2603 |
2571 | 2604 |
2572 HConstant::HConstant(double double_value, | 2605 HConstant::HConstant(double double_value, |
2573 Representation r, | 2606 Representation r, |
2574 bool is_not_in_new_space, | 2607 bool is_not_in_new_space, |
2575 Unique<Object> object) | 2608 Unique<Object> object) |
2576 : object_(object), | 2609 : object_(object), |
2577 has_int32_value_(IsInteger32(double_value)), | 2610 has_int32_value_(IsInteger32(double_value)), |
2578 has_double_value_(true), | 2611 has_double_value_(true), |
2579 has_external_reference_value_(false), | 2612 has_external_reference_value_(false), |
2580 is_internalized_string_(false), | |
2581 is_not_in_new_space_(is_not_in_new_space), | 2613 is_not_in_new_space_(is_not_in_new_space), |
2582 is_cell_(false), | |
2583 boolean_value_(double_value != 0 && !std::isnan(double_value)), | 2614 boolean_value_(double_value != 0 && !std::isnan(double_value)), |
2615 is_undetectable_(false), | |
2584 int32_value_(DoubleToInt32(double_value)), | 2616 int32_value_(DoubleToInt32(double_value)), |
2585 double_value_(double_value) { | 2617 double_value_(double_value), |
2618 instance_type_(kUnknownInstanceType) { | |
2586 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); | 2619 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); |
2587 set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber()); | 2620 set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber()); |
2588 Initialize(r); | 2621 Initialize(r); |
2589 } | 2622 } |
2590 | 2623 |
2591 | 2624 |
2592 HConstant::HConstant(ExternalReference reference) | 2625 HConstant::HConstant(ExternalReference reference) |
2593 : HTemplateInstruction<0>(HType::None()), | 2626 : HTemplateInstruction<0>(HType::None()), |
2594 object_(Unique<Object>(Handle<Object>::null())), | 2627 object_(Unique<Object>(Handle<Object>::null())), |
2595 has_smi_value_(false), | 2628 has_smi_value_(false), |
2596 has_int32_value_(false), | 2629 has_int32_value_(false), |
2597 has_double_value_(false), | 2630 has_double_value_(false), |
2598 has_external_reference_value_(true), | 2631 has_external_reference_value_(true), |
2599 is_internalized_string_(false), | |
2600 is_not_in_new_space_(true), | 2632 is_not_in_new_space_(true), |
2601 is_cell_(false), | |
2602 boolean_value_(true), | 2633 boolean_value_(true), |
2603 external_reference_value_(reference) { | 2634 is_undetectable_(false), |
2635 external_reference_value_(reference), | |
2636 instance_type_(kUnknownInstanceType) { | |
2604 Initialize(Representation::External()); | 2637 Initialize(Representation::External()); |
2605 } | 2638 } |
2606 | 2639 |
2607 | 2640 |
2608 void HConstant::Initialize(Representation r) { | 2641 void HConstant::Initialize(Representation r) { |
2609 if (r.IsNone()) { | 2642 if (r.IsNone()) { |
2610 if (has_smi_value_ && SmiValuesAre31Bits()) { | 2643 if (has_smi_value_ && SmiValuesAre31Bits()) { |
2611 r = Representation::Smi(); | 2644 r = Representation::Smi(); |
2612 } else if (has_int32_value_) { | 2645 } else if (has_int32_value_) { |
2613 r = Representation::Integer32(); | 2646 r = Representation::Integer32(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2692 if (has_double_value_) { | 2725 if (has_double_value_) { |
2693 return new(zone) HConstant(double_value_, r, is_not_in_new_space_, object_); | 2726 return new(zone) HConstant(double_value_, r, is_not_in_new_space_, object_); |
2694 } | 2727 } |
2695 if (has_external_reference_value_) { | 2728 if (has_external_reference_value_) { |
2696 return new(zone) HConstant(external_reference_value_); | 2729 return new(zone) HConstant(external_reference_value_); |
2697 } | 2730 } |
2698 ASSERT(!object_.handle().is_null()); | 2731 ASSERT(!object_.handle().is_null()); |
2699 return new(zone) HConstant(object_, | 2732 return new(zone) HConstant(object_, |
2700 r, | 2733 r, |
2701 type_, | 2734 type_, |
2702 is_internalized_string_, | |
2703 is_not_in_new_space_, | 2735 is_not_in_new_space_, |
2704 is_cell_, | 2736 boolean_value_, |
2705 boolean_value_); | 2737 is_undetectable_, |
2738 instance_type_); | |
2706 } | 2739 } |
2707 | 2740 |
2708 | 2741 |
2709 Maybe<HConstant*> HConstant::CopyToTruncatedInt32(Zone* zone) { | 2742 Maybe<HConstant*> HConstant::CopyToTruncatedInt32(Zone* zone) { |
2710 HConstant* res = NULL; | 2743 HConstant* res = NULL; |
2711 if (has_int32_value_) { | 2744 if (has_int32_value_) { |
2712 res = new(zone) HConstant(int32_value_, | 2745 res = new(zone) HConstant(int32_value_, |
2713 Representation::Integer32(), | 2746 Representation::Integer32(), |
2714 is_not_in_new_space_, | 2747 is_not_in_new_space_, |
2715 object_); | 2748 object_); |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3009 | 3042 |
3010 void HCompareObjectEqAndBranch::PrintDataTo(StringStream* stream) { | 3043 void HCompareObjectEqAndBranch::PrintDataTo(StringStream* stream) { |
3011 left()->PrintNameTo(stream); | 3044 left()->PrintNameTo(stream); |
3012 stream->Add(" "); | 3045 stream->Add(" "); |
3013 right()->PrintNameTo(stream); | 3046 right()->PrintNameTo(stream); |
3014 HControlInstruction::PrintDataTo(stream); | 3047 HControlInstruction::PrintDataTo(stream); |
3015 } | 3048 } |
3016 | 3049 |
3017 | 3050 |
3018 bool HCompareObjectEqAndBranch::KnownSuccessorBlock(HBasicBlock** block) { | 3051 bool HCompareObjectEqAndBranch::KnownSuccessorBlock(HBasicBlock** block) { |
3019 if (left()->IsConstant() && right()->IsConstant()) { | 3052 if (FLAG_fold_constants && left()->IsConstant() && right()->IsConstant()) { |
3020 bool comparison_result = | 3053 *block = HConstant::cast(left())->Equals(HConstant::cast(right())) |
3021 HConstant::cast(left())->Equals(HConstant::cast(right())); | 3054 ? FirstSuccessor() : SecondSuccessor(); |
3022 *block = comparison_result | |
3023 ? FirstSuccessor() | |
3024 : SecondSuccessor(); | |
3025 return true; | 3055 return true; |
3026 } | 3056 } |
3027 *block = NULL; | 3057 *block = NULL; |
3058 return false; | |
3059 } | |
3060 | |
3061 | |
3062 bool ConstantIsObject(HConstant* constant, Isolate* isolate) { | |
3063 if (constant->HasNumberValue()) return false; | |
3064 if (constant->GetUnique().IsKnownGlobal(isolate->heap()->null_value())) { | |
3065 return true; | |
3066 } | |
3067 if (constant->IsUndetectable()) return false; | |
3068 InstanceType type = constant->GetInstanceType(); | |
3069 return (FIRST_NONCALLABLE_SPEC_OBJECT_TYPE <= type) && | |
3070 (type <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | |
3071 } | |
3072 | |
3073 | |
3074 bool HIsObjectAndBranch::KnownSuccessorBlock(HBasicBlock** block) { | |
3075 if (FLAG_fold_constants && value()->IsConstant()) { | |
3076 *block = ConstantIsObject(HConstant::cast(value()), isolate()) | |
3077 ? FirstSuccessor() : SecondSuccessor(); | |
3078 return true; | |
3079 } | |
3080 *block = NULL; | |
3081 return false; | |
3082 } | |
3083 | |
3084 | |
3085 bool HIsStringAndBranch::KnownSuccessorBlock(HBasicBlock** block) { | |
3086 if (FLAG_fold_constants && value()->IsConstant()) { | |
3087 *block = HConstant::cast(value())->HasStringValue() | |
3088 ? FirstSuccessor() : SecondSuccessor(); | |
3089 return true; | |
3090 } | |
3091 *block = NULL; | |
3092 return false; | |
3093 } | |
3094 | |
3095 | |
3096 bool HIsSmiAndBranch::KnownSuccessorBlock(HBasicBlock** block) { | |
3097 if (FLAG_fold_constants && value()->IsConstant()) { | |
3098 *block = HConstant::cast(value())->HasSmiValue() | |
3099 ? FirstSuccessor() : SecondSuccessor(); | |
3100 return true; | |
3101 } | |
3102 *block = NULL; | |
3103 return false; | |
3104 } | |
3105 | |
3106 | |
3107 bool HIsUndetectableAndBranch::KnownSuccessorBlock(HBasicBlock** block) { | |
3108 if (FLAG_fold_constants && value()->IsConstant()) { | |
3109 *block = HConstant::cast(value())->IsUndetectable() | |
3110 ? FirstSuccessor() : SecondSuccessor(); | |
3111 return true; | |
3112 } | |
3113 *block = NULL; | |
3114 return false; | |
3115 } | |
3116 | |
3117 | |
3118 bool HHasInstanceTypeAndBranch::KnownSuccessorBlock(HBasicBlock** block) { | |
3119 if (FLAG_fold_constants && value()->IsConstant()) { | |
3120 InstanceType type = HConstant::cast(value())->GetInstanceType(); | |
3121 *block = (from_ <= type) && (type <= to_) | |
3122 ? FirstSuccessor() : SecondSuccessor(); | |
3123 return true; | |
3124 } | |
3125 *block = NULL; | |
3028 return false; | 3126 return false; |
3029 } | 3127 } |
3030 | 3128 |
3031 | 3129 |
3032 void HCompareHoleAndBranch::InferRepresentation( | 3130 void HCompareHoleAndBranch::InferRepresentation( |
3033 HInferRepresentationPhase* h_infer) { | 3131 HInferRepresentationPhase* h_infer) { |
3034 ChangeRepresentation(value()->representation()); | 3132 ChangeRepresentation(value()->representation()); |
3035 } | 3133 } |
3036 | 3134 |
3037 | 3135 |
3038 bool HCompareMinusZeroAndBranch::KnownSuccessorBlock(HBasicBlock** block) { | 3136 bool HCompareMinusZeroAndBranch::KnownSuccessorBlock(HBasicBlock** block) { |
3137 if (FLAG_fold_constants && value()->IsConstant()) { | |
3138 HConstant* constant = HConstant::cast(value()); | |
3139 if (constant->HasDoubleValue()) { | |
3140 *block = IsMinusZero(constant->DoubleValue()) | |
3141 ? FirstSuccessor() : SecondSuccessor(); | |
3142 } | |
Jakob Kummerow
2014/03/07 18:32:35
I think you're missing a "return true;" here.
| |
3143 } | |
3039 if (value()->representation().IsSmiOrInteger32()) { | 3144 if (value()->representation().IsSmiOrInteger32()) { |
3040 // A Smi or Integer32 cannot contain minus zero. | 3145 // A Smi or Integer32 cannot contain minus zero. |
3041 *block = SecondSuccessor(); | 3146 *block = SecondSuccessor(); |
3042 return true; | 3147 return true; |
3043 } | 3148 } |
3044 *block = NULL; | 3149 *block = NULL; |
3045 return false; | 3150 return false; |
3046 } | 3151 } |
3047 | 3152 |
3048 | 3153 |
(...skipping 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4523 break; | 4628 break; |
4524 case kExternalMemory: | 4629 case kExternalMemory: |
4525 stream->Add("[external-memory]"); | 4630 stream->Add("[external-memory]"); |
4526 break; | 4631 break; |
4527 } | 4632 } |
4528 | 4633 |
4529 stream->Add("@%d", offset()); | 4634 stream->Add("@%d", offset()); |
4530 } | 4635 } |
4531 | 4636 |
4532 } } // namespace v8::internal | 4637 } } // namespace v8::internal |
OLD | NEW |