| 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 1568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1579 | 1579 |
| 1580 HValue* element = | 1580 HValue* element = |
| 1581 AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL, | 1581 AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL, |
| 1582 from_elements_kind, | 1582 from_elements_kind, |
| 1583 ALLOW_RETURN_HOLE)); | 1583 ALLOW_RETURN_HOLE)); |
| 1584 | 1584 |
| 1585 ElementsKind holey_kind = IsFastSmiElementsKind(to_elements_kind) | 1585 ElementsKind holey_kind = IsFastSmiElementsKind(to_elements_kind) |
| 1586 ? FAST_HOLEY_ELEMENTS : to_elements_kind; | 1586 ? FAST_HOLEY_ELEMENTS : to_elements_kind; |
| 1587 HInstruction* holey_store = AddInstruction( | 1587 HInstruction* holey_store = AddInstruction( |
| 1588 new(zone()) HStoreKeyed(to_elements, key, element, holey_kind)); | 1588 new(zone()) HStoreKeyed(to_elements, key, element, holey_kind)); |
| 1589 holey_store->ClearFlag(HValue::kDeoptimizeOnUndefined); | 1589 // Allow NaN hole values to converted to their tagged counterparts. |
| 1590 if (IsFastHoleyElementsKind(to_elements_kind)) { |
| 1591 holey_store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 1592 } |
| 1590 | 1593 |
| 1591 builder.EndBody(); | 1594 builder.EndBody(); |
| 1592 | 1595 |
| 1593 if (!pre_fill_with_holes && length != capacity) { | 1596 if (!pre_fill_with_holes && length != capacity) { |
| 1594 // Fill unused capacity with the hole. | 1597 // Fill unused capacity with the hole. |
| 1595 BuildFillElementsWithHole(context, to_elements, to_elements_kind, | 1598 BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
| 1596 key, capacity); | 1599 key, capacity); |
| 1597 } | 1600 } |
| 1598 } | 1601 } |
| 1599 | 1602 |
| (...skipping 1493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3093 next = use_value->block()->predecessors()->at(use_index)->end(); | 3096 next = use_value->block()->predecessors()->at(use_index)->end(); |
| 3094 } else { | 3097 } else { |
| 3095 next = HInstruction::cast(use_value); | 3098 next = HInstruction::cast(use_value); |
| 3096 } | 3099 } |
| 3097 // For constants we try to make the representation change at compile | 3100 // For constants we try to make the representation change at compile |
| 3098 // time. When a representation change is not possible without loss of | 3101 // time. When a representation change is not possible without loss of |
| 3099 // information we treat constants like normal instructions and insert the | 3102 // information we treat constants like normal instructions and insert the |
| 3100 // change instructions for them. | 3103 // change instructions for them. |
| 3101 HInstruction* new_value = NULL; | 3104 HInstruction* new_value = NULL; |
| 3102 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); | 3105 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); |
| 3103 bool deoptimize_on_undefined = | 3106 bool allow_undefined_as_nan = |
| 3104 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined); | 3107 use_value->CheckFlag(HValue::kAllowUndefinedAsNaN); |
| 3105 if (value->IsConstant()) { | 3108 if (value->IsConstant()) { |
| 3106 HConstant* constant = HConstant::cast(value); | 3109 HConstant* constant = HConstant::cast(value); |
| 3107 // Try to create a new copy of the constant with the new representation. | 3110 // Try to create a new copy of the constant with the new representation. |
| 3108 new_value = (is_truncating && to.IsInteger32()) | 3111 new_value = (is_truncating && to.IsInteger32()) |
| 3109 ? constant->CopyToTruncatedInt32(zone()) | 3112 ? constant->CopyToTruncatedInt32(zone()) |
| 3110 : constant->CopyToRepresentation(to, zone()); | 3113 : constant->CopyToRepresentation(to, zone()); |
| 3111 } | 3114 } |
| 3112 | 3115 |
| 3113 if (new_value == NULL) { | 3116 if (new_value == NULL) { |
| 3114 new_value = new(zone()) HChange(value, to, | 3117 new_value = new(zone()) HChange(value, to, |
| 3115 is_truncating, deoptimize_on_undefined); | 3118 is_truncating, allow_undefined_as_nan); |
| 3116 } | 3119 } |
| 3117 | 3120 |
| 3118 new_value->InsertBefore(next); | 3121 new_value->InsertBefore(next); |
| 3119 use_value->SetOperandAt(use_index, new_value); | 3122 use_value->SetOperandAt(use_index, new_value); |
| 3120 } | 3123 } |
| 3121 | 3124 |
| 3122 | 3125 |
| 3123 void HGraph::InsertRepresentationChangesForValue(HValue* value) { | 3126 void HGraph::InsertRepresentationChangesForValue(HValue* value) { |
| 3124 Representation r = value->representation(); | 3127 Representation r = value->representation(); |
| 3125 if (r.IsNone()) return; | 3128 if (r.IsNone()) return; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3212 while (current != NULL) { | 3215 while (current != NULL) { |
| 3213 HInstruction* next = current->next(); | 3216 HInstruction* next = current->next(); |
| 3214 InsertRepresentationChangesForValue(current); | 3217 InsertRepresentationChangesForValue(current); |
| 3215 current = next; | 3218 current = next; |
| 3216 } | 3219 } |
| 3217 } | 3220 } |
| 3218 } | 3221 } |
| 3219 | 3222 |
| 3220 | 3223 |
| 3221 void HGraph::RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi) { | 3224 void HGraph::RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi) { |
| 3222 if (phi->CheckFlag(HValue::kDeoptimizeOnUndefined)) return; | 3225 if (!phi->CheckFlag(HValue::kAllowUndefinedAsNaN)) return; |
| 3223 phi->SetFlag(HValue::kDeoptimizeOnUndefined); | 3226 phi->ClearFlag(HValue::kAllowUndefinedAsNaN); |
| 3224 for (int i = 0; i < phi->OperandCount(); ++i) { | 3227 for (int i = 0; i < phi->OperandCount(); ++i) { |
| 3225 HValue* input = phi->OperandAt(i); | 3228 HValue* input = phi->OperandAt(i); |
| 3226 if (input->IsPhi()) { | 3229 if (input->IsPhi()) { |
| 3227 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input)); | 3230 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input)); |
| 3228 } | 3231 } |
| 3229 } | 3232 } |
| 3230 } | 3233 } |
| 3231 | 3234 |
| 3232 | 3235 |
| 3233 void HGraph::MarkDeoptimizeOnUndefined() { | 3236 void HGraph::MarkDeoptimizeOnUndefined() { |
| 3234 HPhase phase("H_MarkDeoptimizeOnUndefined", this); | 3237 HPhase phase("H_MarkDeoptimizeOnUndefined", this); |
| 3235 // Compute DeoptimizeOnUndefined flag for phis. | 3238 // Compute DeoptimizeOnUndefined flag for phis. |
| 3236 // Any phi that can reach a use with DeoptimizeOnUndefined set must | 3239 // Any phi that can reach a use with DeoptimizeOnUndefined set must |
| 3237 // have DeoptimizeOnUndefined set. Currently only HCompareIDAndBranch, with | 3240 // have DeoptimizeOnUndefined set. Currently only HCompareIDAndBranch, with |
| 3238 // double input representation, has this flag set. | 3241 // double input representation, has this flag set. |
| 3239 // The flag is used by HChange tagged->double, which must deoptimize | 3242 // The flag is used by HChange tagged->double, which must deoptimize |
| 3240 // if one of its uses has this flag set. | 3243 // if one of its uses has this flag set. |
| 3241 for (int i = 0; i < phi_list()->length(); i++) { | 3244 for (int i = 0; i < phi_list()->length(); i++) { |
| 3242 HPhi* phi = phi_list()->at(i); | 3245 HPhi* phi = phi_list()->at(i); |
| 3243 if (phi->representation().IsDouble()) { | 3246 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { |
| 3244 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { | 3247 HValue* use_value = it.value(); |
| 3245 int use_index = it.index(); | 3248 if (!use_value->CheckFlag(HValue::kAllowUndefinedAsNaN)) { |
| 3246 HValue* use_value = it.value(); | 3249 RecursivelyMarkPhiDeoptimizeOnUndefined(phi); |
| 3247 Representation req = use_value->RequiredInputRepresentation(use_index); | 3250 break; |
| 3248 if (!req.IsDouble() || | |
| 3249 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined)) { | |
| 3250 RecursivelyMarkPhiDeoptimizeOnUndefined(phi); | |
| 3251 break; | |
| 3252 } | |
| 3253 } | 3251 } |
| 3254 } | 3252 } |
| 3255 } | 3253 } |
| 3256 } | 3254 } |
| 3257 | 3255 |
| 3258 | 3256 |
| 3259 // Discover instructions that can be marked with kUint32 flag allowing | 3257 // Discover instructions that can be marked with kUint32 flag allowing |
| 3260 // them to produce full range uint32 values. | 3258 // them to produce full range uint32 values. |
| 3261 class Uint32Analysis BASE_EMBEDDED { | 3259 class Uint32Analysis BASE_EMBEDDED { |
| 3262 public: | 3260 public: |
| (...skipping 6839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10102 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( | 10100 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( |
| 10103 elements, Representation::Tagged())); | 10101 elements, Representation::Tagged())); |
| 10104 int elements_length = elements->length(); | 10102 int elements_length = elements->length(); |
| 10105 for (int i = 0; i < elements_length; i++) { | 10103 for (int i = 0; i < elements_length; i++) { |
| 10106 HValue* key_constant = AddInstruction(new(zone) HConstant(i)); | 10104 HValue* key_constant = AddInstruction(new(zone) HConstant(i)); |
| 10107 HInstruction* value_instruction = | 10105 HInstruction* value_instruction = |
| 10108 AddInstruction(new(zone) HLoadKeyed( | 10106 AddInstruction(new(zone) HLoadKeyed( |
| 10109 boilerplate_elements, key_constant, NULL, kind, ALLOW_RETURN_HOLE)); | 10107 boilerplate_elements, key_constant, NULL, kind, ALLOW_RETURN_HOLE)); |
| 10110 HInstruction* store = AddInstruction(new(zone) HStoreKeyed( | 10108 HInstruction* store = AddInstruction(new(zone) HStoreKeyed( |
| 10111 object_elements, key_constant, value_instruction, kind)); | 10109 object_elements, key_constant, value_instruction, kind)); |
| 10112 store->ClearFlag(HValue::kDeoptimizeOnUndefined); | 10110 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 10113 } | 10111 } |
| 10114 } | 10112 } |
| 10115 | 10113 |
| 10116 | 10114 |
| 10117 void HOptimizedGraphBuilder::BuildEmitFixedArray( | 10115 void HOptimizedGraphBuilder::BuildEmitFixedArray( |
| 10118 Handle<FixedArrayBase> elements, | 10116 Handle<FixedArrayBase> elements, |
| 10119 Handle<FixedArrayBase> original_elements, | 10117 Handle<FixedArrayBase> original_elements, |
| 10120 ElementsKind kind, | 10118 ElementsKind kind, |
| 10121 HValue* object_elements, | 10119 HValue* object_elements, |
| 10122 HInstruction* target, | 10120 HInstruction* target, |
| (...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11498 } | 11496 } |
| 11499 } | 11497 } |
| 11500 | 11498 |
| 11501 #ifdef DEBUG | 11499 #ifdef DEBUG |
| 11502 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11500 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 11503 if (allocator_ != NULL) allocator_->Verify(); | 11501 if (allocator_ != NULL) allocator_->Verify(); |
| 11504 #endif | 11502 #endif |
| 11505 } | 11503 } |
| 11506 | 11504 |
| 11507 } } // namespace v8::internal | 11505 } } // namespace v8::internal |
| OLD | NEW |