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 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 | 493 |
494 int visited_count_; | 494 int visited_count_; |
495 ZoneList<HBasicBlock*> stack_; | 495 ZoneList<HBasicBlock*> stack_; |
496 BitVector reachable_; | 496 BitVector reachable_; |
497 HBasicBlock* dont_visit_; | 497 HBasicBlock* dont_visit_; |
498 }; | 498 }; |
499 | 499 |
500 | 500 |
501 void HGraph::Verify(bool do_full_verify) const { | 501 void HGraph::Verify(bool do_full_verify) const { |
502 // Allow dereferencing for debug mode verification. | 502 // Allow dereferencing for debug mode verification. |
503 AllowHandleDereference allow_handle_deref; | 503 AllowHandleDereference allow_handle_deref(isolate()); |
504 for (int i = 0; i < blocks_.length(); i++) { | 504 for (int i = 0; i < blocks_.length(); i++) { |
505 HBasicBlock* block = blocks_.at(i); | 505 HBasicBlock* block = blocks_.at(i); |
506 | 506 |
507 block->Verify(); | 507 block->Verify(); |
508 | 508 |
509 // Check that every block contains at least one node and that only the last | 509 // Check that every block contains at least one node and that only the last |
510 // node is a control instruction. | 510 // node is a control instruction. |
511 HInstruction* current = block->first(); | 511 HInstruction* current = block->first(); |
512 ASSERT(current != NULL && current->IsBlockEntry()); | 512 ASSERT(current != NULL && current->IsBlockEntry()); |
513 while (current != NULL) { | 513 while (current != NULL) { |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 if (mapcheck != NULL) { | 923 if (mapcheck != NULL) { |
924 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 924 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
925 } | 925 } |
926 } | 926 } |
927 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); | 927 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); |
928 bool fast_elements = IsFastObjectElementsKind(elements_kind); | 928 bool fast_elements = IsFastObjectElementsKind(elements_kind); |
929 HInstruction* elements = | 929 HInstruction* elements = |
930 AddInstruction(new(zone) HLoadElements(object, mapcheck)); | 930 AddInstruction(new(zone) HLoadElements(object, mapcheck)); |
931 if (is_store && (fast_elements || fast_smi_only_elements)) { | 931 if (is_store && (fast_elements || fast_smi_only_elements)) { |
932 HCheckMaps* check_cow_map = new(zone) HCheckMaps( | 932 HCheckMaps* check_cow_map = new(zone) HCheckMaps( |
933 elements, Isolate::Current()->factory()->fixed_array_map(), zone); | 933 elements, graph()->isolate()->factory()->fixed_array_map(), zone); |
934 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 934 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
935 AddInstruction(check_cow_map); | 935 AddInstruction(check_cow_map); |
936 } | 936 } |
937 HInstruction* length = NULL; | 937 HInstruction* length = NULL; |
938 HInstruction* checked_key = NULL; | 938 HInstruction* checked_key = NULL; |
939 if (IsExternalArrayElementsKind(elements_kind)) { | 939 if (IsExternalArrayElementsKind(elements_kind)) { |
940 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 940 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
941 checked_key = AddBoundsCheck( | 941 checked_key = AddBoundsCheck( |
942 key, length, ALLOW_SMI_KEY, checked_index_representation); | 942 key, length, ALLOW_SMI_KEY, checked_index_representation); |
943 HLoadExternalArrayPointer* external_elements = | 943 HLoadExternalArrayPointer* external_elements = |
(...skipping 4202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5146 | 5146 |
5147 HInstruction* array = AddInstruction( | 5147 HInstruction* array = AddInstruction( |
5148 new(zone()) HForInCacheArray( | 5148 new(zone()) HForInCacheArray( |
5149 enumerable, | 5149 enumerable, |
5150 map, | 5150 map, |
5151 DescriptorArray::kEnumCacheBridgeCacheIndex)); | 5151 DescriptorArray::kEnumCacheBridgeCacheIndex)); |
5152 | 5152 |
5153 HInstruction* enum_length = AddInstruction(new(zone()) HMapEnumLength(map)); | 5153 HInstruction* enum_length = AddInstruction(new(zone()) HMapEnumLength(map)); |
5154 | 5154 |
5155 HInstruction* start_index = AddInstruction(new(zone()) HConstant( | 5155 HInstruction* start_index = AddInstruction(new(zone()) HConstant( |
5156 Handle<Object>(Smi::FromInt(0)), Representation::Integer32())); | 5156 Handle<Object>(Smi::FromInt(0), isolate()), Representation::Integer32())); |
5157 | 5157 |
5158 Push(map); | 5158 Push(map); |
5159 Push(array); | 5159 Push(array); |
5160 Push(enum_length); | 5160 Push(enum_length); |
5161 Push(start_index); | 5161 Push(start_index); |
5162 | 5162 |
5163 HInstruction* index_cache = AddInstruction( | 5163 HInstruction* index_cache = AddInstruction( |
5164 new(zone()) HForInCacheArray( | 5164 new(zone()) HForInCacheArray( |
5165 enumerable, | 5165 enumerable, |
5166 map, | 5166 map, |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5496 | 5496 |
5497 | 5497 |
5498 // Tries to find a JavaScript accessor of the given name in the prototype chain | 5498 // Tries to find a JavaScript accessor of the given name in the prototype chain |
5499 // starting at the given map. Return true iff there is one, including the | 5499 // starting at the given map. Return true iff there is one, including the |
5500 // corresponding AccessorPair plus its holder (which could be null when the | 5500 // corresponding AccessorPair plus its holder (which could be null when the |
5501 // accessor is found directly in the given map). | 5501 // accessor is found directly in the given map). |
5502 static bool LookupAccessorPair(Handle<Map> map, | 5502 static bool LookupAccessorPair(Handle<Map> map, |
5503 Handle<String> name, | 5503 Handle<String> name, |
5504 Handle<AccessorPair>* accessors, | 5504 Handle<AccessorPair>* accessors, |
5505 Handle<JSObject>* holder) { | 5505 Handle<JSObject>* holder) { |
5506 LookupResult lookup(map->GetIsolate()); | 5506 Isolate* isolate = map->GetIsolate(); |
| 5507 LookupResult lookup(isolate); |
5507 | 5508 |
5508 // Check for a JavaScript accessor directly in the map. | 5509 // Check for a JavaScript accessor directly in the map. |
5509 map->LookupDescriptor(NULL, *name, &lookup); | 5510 map->LookupDescriptor(NULL, *name, &lookup); |
5510 if (lookup.IsPropertyCallbacks()) { | 5511 if (lookup.IsPropertyCallbacks()) { |
5511 Handle<Object> callback(lookup.GetValueFromMap(*map)); | 5512 Handle<Object> callback(lookup.GetValueFromMap(*map), isolate); |
5512 if (!callback->IsAccessorPair()) return false; | 5513 if (!callback->IsAccessorPair()) return false; |
5513 *accessors = Handle<AccessorPair>::cast(callback); | 5514 *accessors = Handle<AccessorPair>::cast(callback); |
5514 *holder = Handle<JSObject>(); | 5515 *holder = Handle<JSObject>(); |
5515 return true; | 5516 return true; |
5516 } | 5517 } |
5517 | 5518 |
5518 // Everything else, e.g. a field, can't be an accessor call. | 5519 // Everything else, e.g. a field, can't be an accessor call. |
5519 if (lookup.IsFound()) return false; | 5520 if (lookup.IsFound()) return false; |
5520 | 5521 |
5521 // Check for a JavaScript accessor somewhere in the proto chain. | 5522 // Check for a JavaScript accessor somewhere in the proto chain. |
5522 LookupInPrototypes(map, name, &lookup); | 5523 LookupInPrototypes(map, name, &lookup); |
5523 if (lookup.IsPropertyCallbacks()) { | 5524 if (lookup.IsPropertyCallbacks()) { |
5524 Handle<Object> callback(lookup.GetValue()); | 5525 Handle<Object> callback(lookup.GetValue(), isolate); |
5525 if (!callback->IsAccessorPair()) return false; | 5526 if (!callback->IsAccessorPair()) return false; |
5526 *accessors = Handle<AccessorPair>::cast(callback); | 5527 *accessors = Handle<AccessorPair>::cast(callback); |
5527 *holder = Handle<JSObject>(lookup.holder()); | 5528 *holder = Handle<JSObject>(lookup.holder()); |
5528 return true; | 5529 return true; |
5529 } | 5530 } |
5530 | 5531 |
5531 // We haven't found a JavaScript accessor anywhere. | 5532 // We haven't found a JavaScript accessor anywhere. |
5532 return false; | 5533 return false; |
5533 } | 5534 } |
5534 | 5535 |
(...skipping 29 matching lines...) Expand all Loading... |
5564 // Determines whether the given array or object literal boilerplate satisfies | 5565 // Determines whether the given array or object literal boilerplate satisfies |
5565 // all limits to be considered for fast deep-copying and computes the total | 5566 // all limits to be considered for fast deep-copying and computes the total |
5566 // size of all objects that are part of the graph. | 5567 // size of all objects that are part of the graph. |
5567 static bool IsFastLiteral(Handle<JSObject> boilerplate, | 5568 static bool IsFastLiteral(Handle<JSObject> boilerplate, |
5568 int max_depth, | 5569 int max_depth, |
5569 int* max_properties, | 5570 int* max_properties, |
5570 int* total_size) { | 5571 int* total_size) { |
5571 ASSERT(max_depth >= 0 && *max_properties >= 0); | 5572 ASSERT(max_depth >= 0 && *max_properties >= 0); |
5572 if (max_depth == 0) return false; | 5573 if (max_depth == 0) return false; |
5573 | 5574 |
| 5575 Isolate* isolate = boilerplate->GetIsolate(); |
5574 Handle<FixedArrayBase> elements(boilerplate->elements()); | 5576 Handle<FixedArrayBase> elements(boilerplate->elements()); |
5575 if (elements->length() > 0 && | 5577 if (elements->length() > 0 && |
5576 elements->map() != boilerplate->GetHeap()->fixed_cow_array_map()) { | 5578 elements->map() != isolate->heap()->fixed_cow_array_map()) { |
5577 if (boilerplate->HasFastDoubleElements()) { | 5579 if (boilerplate->HasFastDoubleElements()) { |
5578 *total_size += FixedDoubleArray::SizeFor(elements->length()); | 5580 *total_size += FixedDoubleArray::SizeFor(elements->length()); |
5579 } else if (boilerplate->HasFastObjectElements()) { | 5581 } else if (boilerplate->HasFastObjectElements()) { |
5580 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 5582 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
5581 int length = elements->length(); | 5583 int length = elements->length(); |
5582 for (int i = 0; i < length; i++) { | 5584 for (int i = 0; i < length; i++) { |
5583 if ((*max_properties)-- == 0) return false; | 5585 if ((*max_properties)-- == 0) return false; |
5584 Handle<Object> value(fast_elements->get(i)); | 5586 Handle<Object> value(fast_elements->get(i), isolate); |
5585 if (value->IsJSObject()) { | 5587 if (value->IsJSObject()) { |
5586 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 5588 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
5587 if (!IsFastLiteral(value_object, | 5589 if (!IsFastLiteral(value_object, |
5588 max_depth - 1, | 5590 max_depth - 1, |
5589 max_properties, | 5591 max_properties, |
5590 total_size)) { | 5592 total_size)) { |
5591 return false; | 5593 return false; |
5592 } | 5594 } |
5593 } | 5595 } |
5594 } | 5596 } |
5595 *total_size += FixedArray::SizeFor(length); | 5597 *total_size += FixedArray::SizeFor(length); |
5596 } else { | 5598 } else { |
5597 return false; | 5599 return false; |
5598 } | 5600 } |
5599 } | 5601 } |
5600 | 5602 |
5601 Handle<FixedArray> properties(boilerplate->properties()); | 5603 Handle<FixedArray> properties(boilerplate->properties()); |
5602 if (properties->length() > 0) { | 5604 if (properties->length() > 0) { |
5603 return false; | 5605 return false; |
5604 } else { | 5606 } else { |
5605 int nof = boilerplate->map()->inobject_properties(); | 5607 int nof = boilerplate->map()->inobject_properties(); |
5606 for (int i = 0; i < nof; i++) { | 5608 for (int i = 0; i < nof; i++) { |
5607 if ((*max_properties)-- == 0) return false; | 5609 if ((*max_properties)-- == 0) return false; |
5608 Handle<Object> value(boilerplate->InObjectPropertyAt(i)); | 5610 Handle<Object> value(boilerplate->InObjectPropertyAt(i), isolate); |
5609 if (value->IsJSObject()) { | 5611 if (value->IsJSObject()) { |
5610 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 5612 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
5611 if (!IsFastLiteral(value_object, | 5613 if (!IsFastLiteral(value_object, |
5612 max_depth - 1, | 5614 max_depth - 1, |
5613 max_properties, | 5615 max_properties, |
5614 total_size)) { | 5616 total_size)) { |
5615 return false; | 5617 return false; |
5616 } | 5618 } |
5617 } | 5619 } |
5618 } | 5620 } |
5619 } | 5621 } |
5620 | 5622 |
5621 *total_size += boilerplate->map()->instance_size(); | 5623 *total_size += boilerplate->map()->instance_size(); |
5622 return true; | 5624 return true; |
5623 } | 5625 } |
5624 | 5626 |
5625 | 5627 |
5626 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 5628 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
5627 ASSERT(!HasStackOverflow()); | 5629 ASSERT(!HasStackOverflow()); |
5628 ASSERT(current_block() != NULL); | 5630 ASSERT(current_block() != NULL); |
5629 ASSERT(current_block()->HasPredecessor()); | 5631 ASSERT(current_block()->HasPredecessor()); |
5630 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); | 5632 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); |
5631 HValue* context = environment()->LookupContext(); | 5633 HValue* context = environment()->LookupContext(); |
5632 HInstruction* literal; | 5634 HInstruction* literal; |
5633 | 5635 |
5634 // Check whether to use fast or slow deep-copying for boilerplate. | 5636 // Check whether to use fast or slow deep-copying for boilerplate. |
5635 int total_size = 0; | 5637 int total_size = 0; |
5636 int max_properties = HFastLiteral::kMaxLiteralProperties; | 5638 int max_properties = HFastLiteral::kMaxLiteralProperties; |
5637 Handle<Object> boilerplate(closure->literals()->get(expr->literal_index())); | 5639 Handle<Object> boilerplate(closure->literals()->get(expr->literal_index()), |
| 5640 isolate()); |
5638 if (boilerplate->IsJSObject() && | 5641 if (boilerplate->IsJSObject() && |
5639 IsFastLiteral(Handle<JSObject>::cast(boilerplate), | 5642 IsFastLiteral(Handle<JSObject>::cast(boilerplate), |
5640 HFastLiteral::kMaxLiteralDepth, | 5643 HFastLiteral::kMaxLiteralDepth, |
5641 &max_properties, | 5644 &max_properties, |
5642 &total_size)) { | 5645 &total_size)) { |
5643 Handle<JSObject> boilerplate_object = Handle<JSObject>::cast(boilerplate); | 5646 Handle<JSObject> boilerplate_object = Handle<JSObject>::cast(boilerplate); |
5644 literal = new(zone()) HFastLiteral(context, | 5647 literal = new(zone()) HFastLiteral(context, |
5645 boilerplate_object, | 5648 boilerplate_object, |
5646 total_size, | 5649 total_size, |
5647 expr->literal_index(), | 5650 expr->literal_index(), |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5732 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { | 5735 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
5733 ASSERT(!HasStackOverflow()); | 5736 ASSERT(!HasStackOverflow()); |
5734 ASSERT(current_block() != NULL); | 5737 ASSERT(current_block() != NULL); |
5735 ASSERT(current_block()->HasPredecessor()); | 5738 ASSERT(current_block()->HasPredecessor()); |
5736 ZoneList<Expression*>* subexprs = expr->values(); | 5739 ZoneList<Expression*>* subexprs = expr->values(); |
5737 int length = subexprs->length(); | 5740 int length = subexprs->length(); |
5738 HValue* context = environment()->LookupContext(); | 5741 HValue* context = environment()->LookupContext(); |
5739 HInstruction* literal; | 5742 HInstruction* literal; |
5740 | 5743 |
5741 Handle<FixedArray> literals(environment()->closure()->literals()); | 5744 Handle<FixedArray> literals(environment()->closure()->literals()); |
5742 Handle<Object> raw_boilerplate(literals->get(expr->literal_index())); | 5745 Handle<Object> raw_boilerplate(literals->get(expr->literal_index()), |
| 5746 isolate()); |
5743 | 5747 |
5744 if (raw_boilerplate->IsUndefined()) { | 5748 if (raw_boilerplate->IsUndefined()) { |
5745 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( | 5749 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( |
5746 isolate(), literals, expr->constant_elements()); | 5750 isolate(), literals, expr->constant_elements()); |
5747 if (raw_boilerplate.is_null()) { | 5751 if (raw_boilerplate.is_null()) { |
5748 return Bailout("array boilerplate creation failed"); | 5752 return Bailout("array boilerplate creation failed"); |
5749 } | 5753 } |
5750 literals->set(expr->literal_index(), *raw_boilerplate); | 5754 literals->set(expr->literal_index(), *raw_boilerplate); |
5751 if (JSObject::cast(*raw_boilerplate)->elements()->map() == | 5755 if (JSObject::cast(*raw_boilerplate)->elements()->map() == |
5752 isolate()->heap()->fixed_cow_array_map()) { | 5756 isolate()->heap()->fixed_cow_array_map()) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5804 CHECK_ALIVE(VisitForValue(subexpr)); | 5808 CHECK_ALIVE(VisitForValue(subexpr)); |
5805 HValue* value = Pop(); | 5809 HValue* value = Pop(); |
5806 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); | 5810 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); |
5807 | 5811 |
5808 // Pass in literal as dummy depedency, since the receiver always has | 5812 // Pass in literal as dummy depedency, since the receiver always has |
5809 // elements. | 5813 // elements. |
5810 elements = new(zone()) HLoadElements(literal, literal); | 5814 elements = new(zone()) HLoadElements(literal, literal); |
5811 AddInstruction(elements); | 5815 AddInstruction(elements); |
5812 | 5816 |
5813 HValue* key = AddInstruction( | 5817 HValue* key = AddInstruction( |
5814 new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)), | 5818 new(zone()) HConstant(Handle<Object>(Smi::FromInt(i), isolate()), |
5815 Representation::Integer32())); | 5819 Representation::Integer32())); |
5816 | 5820 |
5817 switch (boilerplate_elements_kind) { | 5821 switch (boilerplate_elements_kind) { |
5818 case FAST_SMI_ELEMENTS: | 5822 case FAST_SMI_ELEMENTS: |
5819 case FAST_HOLEY_SMI_ELEMENTS: | 5823 case FAST_HOLEY_SMI_ELEMENTS: |
5820 // Smi-only arrays need a smi check. | 5824 // Smi-only arrays need a smi check. |
5821 AddInstruction(new(zone()) HCheckSmi(value)); | 5825 AddInstruction(new(zone()) HCheckSmi(value)); |
5822 // Fall through. | 5826 // Fall through. |
5823 case FAST_ELEMENTS: | 5827 case FAST_ELEMENTS: |
5824 case FAST_HOLEY_ELEMENTS: | 5828 case FAST_HOLEY_ELEMENTS: |
(...skipping 1239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7064 | 7068 |
7065 if (function_state()->outer() == NULL) { | 7069 if (function_state()->outer() == NULL) { |
7066 HInstruction* elements = AddInstruction( | 7070 HInstruction* elements = AddInstruction( |
7067 new(zone()) HArgumentsElements(false)); | 7071 new(zone()) HArgumentsElements(false)); |
7068 result = new(zone()) HArgumentsLength(elements); | 7072 result = new(zone()) HArgumentsLength(elements); |
7069 } else { | 7073 } else { |
7070 // Number of arguments without receiver. | 7074 // Number of arguments without receiver. |
7071 int argument_count = environment()-> | 7075 int argument_count = environment()-> |
7072 arguments_environment()->parameter_count() - 1; | 7076 arguments_environment()->parameter_count() - 1; |
7073 result = new(zone()) HConstant( | 7077 result = new(zone()) HConstant( |
7074 Handle<Object>(Smi::FromInt(argument_count)), | 7078 Handle<Object>(Smi::FromInt(argument_count), isolate()), |
7075 Representation::Integer32()); | 7079 Representation::Integer32()); |
7076 } | 7080 } |
7077 } else { | 7081 } else { |
7078 Push(graph()->GetArgumentsObject()); | 7082 Push(graph()->GetArgumentsObject()); |
7079 VisitForValue(expr->key()); | 7083 VisitForValue(expr->key()); |
7080 if (HasStackOverflow() || current_block() == NULL) return true; | 7084 if (HasStackOverflow() || current_block() == NULL) return true; |
7081 HValue* key = Pop(); | 7085 HValue* key = Pop(); |
7082 Drop(1); // Arguments object. | 7086 Drop(1); // Arguments object. |
7083 if (function_state()->outer() == NULL) { | 7087 if (function_state()->outer() == NULL) { |
7084 HInstruction* elements = AddInstruction( | 7088 HInstruction* elements = AddInstruction( |
7085 new(zone()) HArgumentsElements(false)); | 7089 new(zone()) HArgumentsElements(false)); |
7086 HInstruction* length = AddInstruction( | 7090 HInstruction* length = AddInstruction( |
7087 new(zone()) HArgumentsLength(elements)); | 7091 new(zone()) HArgumentsLength(elements)); |
7088 HInstruction* checked_key = AddBoundsCheck(key, length); | 7092 HInstruction* checked_key = AddBoundsCheck(key, length); |
7089 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 7093 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
7090 } else { | 7094 } else { |
7091 EnsureArgumentsArePushedForAccess(); | 7095 EnsureArgumentsArePushedForAccess(); |
7092 | 7096 |
7093 // Number of arguments without receiver. | 7097 // Number of arguments without receiver. |
7094 HInstruction* elements = function_state()->arguments_elements(); | 7098 HInstruction* elements = function_state()->arguments_elements(); |
7095 int argument_count = environment()-> | 7099 int argument_count = environment()-> |
7096 arguments_environment()->parameter_count() - 1; | 7100 arguments_environment()->parameter_count() - 1; |
7097 HInstruction* length = AddInstruction(new(zone()) HConstant( | 7101 HInstruction* length = AddInstruction(new(zone()) HConstant( |
7098 Handle<Object>(Smi::FromInt(argument_count)), | 7102 Handle<Object>(Smi::FromInt(argument_count), isolate()), |
7099 Representation::Integer32())); | 7103 Representation::Integer32())); |
7100 HInstruction* checked_key = AddBoundsCheck(key, length); | 7104 HInstruction* checked_key = AddBoundsCheck(key, length); |
7101 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 7105 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
7102 } | 7106 } |
7103 } | 7107 } |
7104 ast_context()->ReturnInstruction(result, expr->id()); | 7108 ast_context()->ReturnInstruction(result, expr->id()); |
7105 return true; | 7109 return true; |
7106 } | 7110 } |
7107 | 7111 |
7108 | 7112 |
7109 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { | 7113 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
(...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7900 HValue* context = environment()->LookupContext(); | 7904 HValue* context = environment()->LookupContext(); |
7901 HInstruction* result = NULL; | 7905 HInstruction* result = NULL; |
7902 // Use sqrt() if exponent is 0.5 or -0.5. | 7906 // Use sqrt() if exponent is 0.5 or -0.5. |
7903 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { | 7907 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { |
7904 double exponent = HConstant::cast(right)->DoubleValue(); | 7908 double exponent = HConstant::cast(right)->DoubleValue(); |
7905 if (exponent == 0.5) { | 7909 if (exponent == 0.5) { |
7906 result = | 7910 result = |
7907 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); | 7911 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); |
7908 } else if (exponent == -0.5) { | 7912 } else if (exponent == -0.5) { |
7909 HConstant* double_one = | 7913 HConstant* double_one = |
7910 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)), | 7914 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1), |
| 7915 isolate()), |
7911 Representation::Double()); | 7916 Representation::Double()); |
7912 AddInstruction(double_one); | 7917 AddInstruction(double_one); |
7913 HInstruction* sqrt = | 7918 HInstruction* sqrt = |
7914 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); | 7919 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); |
7915 AddInstruction(sqrt); | 7920 AddInstruction(sqrt); |
7916 // MathPowHalf doesn't have side effects so there's no need for | 7921 // MathPowHalf doesn't have side effects so there's no need for |
7917 // an environment simulation here. | 7922 // an environment simulation here. |
7918 ASSERT(!sqrt->HasObservableSideEffects()); | 7923 ASSERT(!sqrt->HasObservableSideEffects()); |
7919 result = HDiv::New(zone(), context, double_one, sqrt); | 7924 result = HDiv::New(zone(), context, double_one, sqrt); |
7920 } else if (exponent == 2.0) { | 7925 } else if (exponent == 2.0) { |
(...skipping 2791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10712 } | 10717 } |
10713 } | 10718 } |
10714 | 10719 |
10715 #ifdef DEBUG | 10720 #ifdef DEBUG |
10716 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 10721 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
10717 if (allocator_ != NULL) allocator_->Verify(); | 10722 if (allocator_ != NULL) allocator_->Verify(); |
10718 #endif | 10723 #endif |
10719 } | 10724 } |
10720 | 10725 |
10721 } } // namespace v8::internal | 10726 } } // namespace v8::internal |
OLD | NEW |