OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 7614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7625 if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) { | 7625 if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) { |
7626 return false; | 7626 return false; |
7627 } | 7627 } |
7628 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; | 7628 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; |
7629 ElementsKind elements_kind = receiver_map->elements_kind(); | 7629 ElementsKind elements_kind = receiver_map->elements_kind(); |
7630 if (!IsFastElementsKind(elements_kind)) return false; | 7630 if (!IsFastElementsKind(elements_kind)) return false; |
7631 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 7631 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
7632 | 7632 |
7633 Drop(expr->arguments()->length()); | 7633 Drop(expr->arguments()->length()); |
7634 HValue* result; | 7634 HValue* result; |
7635 HValue* checked_object; | |
7636 HValue* reduced_length; | 7635 HValue* reduced_length; |
7637 HValue* receiver = Pop(); | 7636 HValue* receiver = Pop(); |
7637 | |
7638 HValue* checked_object = AddCheckMap(receiver, receiver_map); | |
7639 HValue* length = Add<HLoadNamedField>( | |
7640 checked_object, HObjectAccess::ForArrayLength(elements_kind)); | |
7641 | |
7638 { NoObservableSideEffectsScope scope(this); | 7642 { NoObservableSideEffectsScope scope(this); |
7639 checked_object = AddCheckMap(receiver, receiver_map); | 7643 IfBuilder length_checker(this); |
7644 | |
7645 length_checker.If<HCompareNumericAndBranch>( | |
7646 length, graph()->GetConstant0(), Token::EQ); | |
7647 length_checker.Then(); | |
7648 | |
7649 Push(graph()->GetConstantUndefined()); | |
7650 | |
7651 length_checker.Else(); | |
7640 HValue* elements = AddLoadElements(checked_object); | 7652 HValue* elements = AddLoadElements(checked_object); |
7641 // Ensure that we aren't popping from a copy-on-write array. | 7653 // Ensure that we aren't popping from a copy-on-write array. |
7642 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 7654 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
7643 Add<HCheckMaps>( | 7655 elements = BuildCopyElementsOnWrite(checked_object, elements, |
7644 elements, isolate()->factory()->fixed_array_map(), top_info()); | 7656 elements_kind, length); |
7645 } | 7657 } |
7646 HValue* length = Add<HLoadNamedField>( | |
7647 checked_object, HObjectAccess::ForArrayLength(elements_kind)); | |
7648 reduced_length = AddUncasted<HSub>(length, graph()->GetConstant1()); | 7658 reduced_length = AddUncasted<HSub>(length, graph()->GetConstant1()); |
7649 HValue* bounds_check = Add<HBoundsCheck>( | 7659 HValue* bounds_check = Add<HBoundsCheck>( |
7650 graph()->GetConstant0(), length); | 7660 graph()->GetConstant0(), length); |
7651 result = AddElementAccess(elements, reduced_length, NULL, | 7661 result = AddElementAccess(elements, reduced_length, NULL, |
7652 bounds_check, elements_kind, false); | 7662 bounds_check, elements_kind, false); |
7653 Factory* factory = isolate()->factory(); | 7663 Factory* factory = isolate()->factory(); |
7654 double nan_double = FixedDoubleArray::hole_nan_as_double(); | 7664 double nan_double = FixedDoubleArray::hole_nan_as_double(); |
7655 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) | 7665 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) |
7656 ? Add<HConstant>(factory->the_hole_value()) | 7666 ? Add<HConstant>(factory->the_hole_value()) |
7657 : Add<HConstant>(nan_double); | 7667 : Add<HConstant>(nan_double); |
7658 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 7668 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
7659 elements_kind = FAST_HOLEY_ELEMENTS; | 7669 elements_kind = FAST_HOLEY_ELEMENTS; |
7660 } | 7670 } |
7661 AddElementAccess( | 7671 AddElementAccess( |
7662 elements, reduced_length, hole, bounds_check, elements_kind, true); | 7672 elements, reduced_length, hole, bounds_check, elements_kind, true); |
7673 Add<HStoreNamedField>( | |
7674 checked_object, HObjectAccess::ForArrayLength(elements_kind), | |
7675 reduced_length); | |
mvstanton
2014/01/29 10:16:09
I just don't understand why storing the reduced le
| |
7676 | |
7677 Push(result); | |
7678 | |
7679 length_checker.End(); | |
7663 } | 7680 } |
7664 Add<HStoreNamedField>( | 7681 result = ast_context()->IsEffect() ? Pop() : Top(); |
7665 checked_object, HObjectAccess::ForArrayLength(elements_kind), | |
7666 reduced_length); | |
7667 if (!ast_context()->IsEffect()) Push(result); | |
7668 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 7682 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
7669 if (!ast_context()->IsEffect()) Drop(1); | 7683 if (!ast_context()->IsEffect()) Drop(1); |
7684 | |
7670 ast_context()->ReturnValue(result); | 7685 ast_context()->ReturnValue(result); |
7671 return true; | 7686 return true; |
7672 } | 7687 } |
7673 case kArrayPush: { | 7688 case kArrayPush: { |
7674 if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) { | 7689 if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) { |
7675 return false; | 7690 return false; |
7676 } | 7691 } |
7677 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; | 7692 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; |
7678 ElementsKind elements_kind = receiver_map->elements_kind(); | 7693 ElementsKind elements_kind = receiver_map->elements_kind(); |
7679 if (!IsFastElementsKind(elements_kind)) return false; | 7694 if (!IsFastElementsKind(elements_kind)) return false; |
(...skipping 3414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11094 if (ShouldProduceTraceOutput()) { | 11109 if (ShouldProduceTraceOutput()) { |
11095 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11110 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
11096 } | 11111 } |
11097 | 11112 |
11098 #ifdef DEBUG | 11113 #ifdef DEBUG |
11099 graph_->Verify(false); // No full verify. | 11114 graph_->Verify(false); // No full verify. |
11100 #endif | 11115 #endif |
11101 } | 11116 } |
11102 | 11117 |
11103 } } // namespace v8::internal | 11118 } } // namespace v8::internal |
OLD | NEW |