| 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 5504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5515 return false; | 5515 return false; |
| 5516 } | 5516 } |
| 5517 | 5517 |
| 5518 | 5518 |
| 5519 // Determines whether the given array or object literal boilerplate satisfies | 5519 // Determines whether the given array or object literal boilerplate satisfies |
| 5520 // all limits to be considered for fast deep-copying and computes the total | 5520 // all limits to be considered for fast deep-copying and computes the total |
| 5521 // size of all objects that are part of the graph. | 5521 // size of all objects that are part of the graph. |
| 5522 static bool IsFastLiteral(Handle<JSObject> boilerplate, | 5522 static bool IsFastLiteral(Handle<JSObject> boilerplate, |
| 5523 int max_depth, | 5523 int max_depth, |
| 5524 int* max_properties, | 5524 int* max_properties, |
| 5525 int* total_size) { | 5525 int* total_size, |
| 5526 AllocationSiteMode mode) { |
| 5526 ASSERT(max_depth >= 0 && *max_properties >= 0); | 5527 ASSERT(max_depth >= 0 && *max_properties >= 0); |
| 5527 if (max_depth == 0) return false; | 5528 if (max_depth == 0) return false; |
| 5528 | 5529 |
| 5530 if (mode == TRACK_ALLOCATION_SITE && |
| 5531 boilerplate->ShouldTrackAllocationInfo()) { |
| 5532 *total_size += AllocationSiteInfo::kSize; |
| 5533 } |
| 5534 |
| 5529 Handle<FixedArrayBase> elements(boilerplate->elements()); | 5535 Handle<FixedArrayBase> elements(boilerplate->elements()); |
| 5530 if (elements->length() > 0 && | 5536 if (elements->length() > 0 && |
| 5531 elements->map() != boilerplate->GetHeap()->fixed_cow_array_map()) { | 5537 elements->map() != boilerplate->GetHeap()->fixed_cow_array_map()) { |
| 5532 if (boilerplate->HasFastDoubleElements()) { | 5538 if (boilerplate->HasFastDoubleElements()) { |
| 5533 *total_size += FixedDoubleArray::SizeFor(elements->length()); | 5539 *total_size += FixedDoubleArray::SizeFor(elements->length()); |
| 5534 } else if (boilerplate->HasFastObjectElements()) { | 5540 } else if (boilerplate->HasFastObjectElements()) { |
| 5535 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 5541 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
| 5536 int length = elements->length(); | 5542 int length = elements->length(); |
| 5537 for (int i = 0; i < length; i++) { | 5543 for (int i = 0; i < length; i++) { |
| 5538 if ((*max_properties)-- == 0) return false; | 5544 if ((*max_properties)-- == 0) return false; |
| 5539 Handle<Object> value(fast_elements->get(i)); | 5545 Handle<Object> value(fast_elements->get(i)); |
| 5540 if (value->IsJSObject()) { | 5546 if (value->IsJSObject()) { |
| 5541 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 5547 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 5542 if (!IsFastLiteral(value_object, | 5548 if (!IsFastLiteral(value_object, |
| 5543 max_depth - 1, | 5549 max_depth - 1, |
| 5544 max_properties, | 5550 max_properties, |
| 5545 total_size)) { | 5551 total_size, |
| 5552 mode)) { |
| 5546 return false; | 5553 return false; |
| 5547 } | 5554 } |
| 5548 } | 5555 } |
| 5549 } | 5556 } |
| 5550 *total_size += FixedArray::SizeFor(length); | 5557 *total_size += FixedArray::SizeFor(length); |
| 5551 } else { | 5558 } else { |
| 5552 return false; | 5559 return false; |
| 5553 } | 5560 } |
| 5554 } | 5561 } |
| 5555 | 5562 |
| 5556 Handle<FixedArray> properties(boilerplate->properties()); | 5563 Handle<FixedArray> properties(boilerplate->properties()); |
| 5557 if (properties->length() > 0) { | 5564 if (properties->length() > 0) { |
| 5558 return false; | 5565 return false; |
| 5559 } else { | 5566 } else { |
| 5560 int nof = boilerplate->map()->inobject_properties(); | 5567 int nof = boilerplate->map()->inobject_properties(); |
| 5561 for (int i = 0; i < nof; i++) { | 5568 for (int i = 0; i < nof; i++) { |
| 5562 if ((*max_properties)-- == 0) return false; | 5569 if ((*max_properties)-- == 0) return false; |
| 5563 Handle<Object> value(boilerplate->InObjectPropertyAt(i)); | 5570 Handle<Object> value(boilerplate->InObjectPropertyAt(i)); |
| 5564 if (value->IsJSObject()) { | 5571 if (value->IsJSObject()) { |
| 5565 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 5572 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 5566 if (!IsFastLiteral(value_object, | 5573 if (!IsFastLiteral(value_object, |
| 5567 max_depth - 1, | 5574 max_depth - 1, |
| 5568 max_properties, | 5575 max_properties, |
| 5569 total_size)) { | 5576 total_size, |
| 5577 mode)) { |
| 5570 return false; | 5578 return false; |
| 5571 } | 5579 } |
| 5572 } | 5580 } |
| 5573 } | 5581 } |
| 5574 } | 5582 } |
| 5575 | 5583 |
| 5576 *total_size += boilerplate->map()->instance_size(); | 5584 *total_size += boilerplate->map()->instance_size(); |
| 5577 return true; | 5585 return true; |
| 5578 } | 5586 } |
| 5579 | 5587 |
| 5580 | 5588 |
| 5581 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 5589 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
| 5582 ASSERT(!HasStackOverflow()); | 5590 ASSERT(!HasStackOverflow()); |
| 5583 ASSERT(current_block() != NULL); | 5591 ASSERT(current_block() != NULL); |
| 5584 ASSERT(current_block()->HasPredecessor()); | 5592 ASSERT(current_block()->HasPredecessor()); |
| 5585 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); | 5593 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); |
| 5586 HValue* context = environment()->LookupContext(); | 5594 HValue* context = environment()->LookupContext(); |
| 5587 HInstruction* literal; | 5595 HInstruction* literal; |
| 5588 | 5596 |
| 5597 // We don't want to use AllocationSiteInfo when the object literal is |
| 5598 // declared at global scope without a surrounding loop, that means it's |
| 5599 // literal arrays will never be re-created, and therefore don't benefit from |
| 5600 // site info. |
| 5601 AllocationSiteMode mode = FLAG_track_allocation_sites && !IsOneTimeCode() |
| 5602 ? TRACK_ALLOCATION_SITE |
| 5603 : DONT_TRACK_ALLOCATION_SITE; |
| 5604 |
| 5589 // Check whether to use fast or slow deep-copying for boilerplate. | 5605 // Check whether to use fast or slow deep-copying for boilerplate. |
| 5590 int total_size = 0; | 5606 int total_size = 0; |
| 5591 int max_properties = HFastLiteral::kMaxLiteralProperties; | 5607 int max_properties = HFastLiteral::kMaxLiteralProperties; |
| 5592 Handle<Object> boilerplate(closure->literals()->get(expr->literal_index())); | 5608 Handle<Object> original_boilerplate(closure->literals()->get( |
| 5593 if (boilerplate->IsJSObject() && | 5609 expr->literal_index())); |
| 5594 IsFastLiteral(Handle<JSObject>::cast(boilerplate), | 5610 if (original_boilerplate->IsJSObject() && |
| 5611 IsFastLiteral(Handle<JSObject>::cast(original_boilerplate), |
| 5595 HFastLiteral::kMaxLiteralDepth, | 5612 HFastLiteral::kMaxLiteralDepth, |
| 5596 &max_properties, | 5613 &max_properties, |
| 5597 &total_size)) { | 5614 &total_size, |
| 5598 Handle<JSObject> boilerplate_object = Handle<JSObject>::cast(boilerplate); | 5615 mode)) { |
| 5616 // Copy the boilerplate to prevent unsavory sharing between fullcodegen and |
| 5617 // crankshaft. |
| 5618 Handle<JSObject> original_boilerplate_object = |
| 5619 Handle<JSObject>::cast(original_boilerplate); |
| 5620 Handle<JSObject> boilerplate = DeepCopy(original_boilerplate_object); |
| 5599 literal = new(zone()) HFastLiteral(context, | 5621 literal = new(zone()) HFastLiteral(context, |
| 5600 boilerplate_object, | 5622 boilerplate, |
| 5623 original_boilerplate_object, |
| 5601 total_size, | 5624 total_size, |
| 5602 expr->literal_index(), | 5625 expr->literal_index(), |
| 5603 expr->depth(), | 5626 expr->depth(), |
| 5604 DONT_TRACK_ALLOCATION_SITE); | 5627 mode); |
| 5605 } else { | 5628 } else { |
| 5606 literal = new(zone()) HObjectLiteral(context, | 5629 literal = new(zone()) HObjectLiteral(context, |
| 5607 expr->constant_properties(), | 5630 expr->constant_properties(), |
| 5608 expr->fast_elements(), | 5631 expr->fast_elements(), |
| 5609 expr->literal_index(), | 5632 expr->literal_index(), |
| 5610 expr->depth(), | 5633 expr->depth(), |
| 5611 expr->has_function()); | 5634 expr->has_function(), |
| 5635 mode); |
| 5612 } | 5636 } |
| 5613 | 5637 |
| 5614 // The object is expected in the bailout environment during computation | 5638 // The object is expected in the bailout environment during computation |
| 5615 // of the property values and is the value of the entire expression. | 5639 // of the property values and is the value of the entire expression. |
| 5616 PushAndAdd(literal); | 5640 PushAndAdd(literal); |
| 5617 | 5641 |
| 5618 expr->CalculateEmitStore(zone()); | 5642 expr->CalculateEmitStore(zone()); |
| 5619 | 5643 |
| 5620 for (int i = 0; i < expr->properties()->length(); i++) { | 5644 for (int i = 0; i < expr->properties()->length(); i++) { |
| 5621 ObjectLiteral::Property* property = expr->properties()->at(i); | 5645 ObjectLiteral::Property* property = expr->properties()->at(i); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5686 | 5710 |
| 5687 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { | 5711 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
| 5688 ASSERT(!HasStackOverflow()); | 5712 ASSERT(!HasStackOverflow()); |
| 5689 ASSERT(current_block() != NULL); | 5713 ASSERT(current_block() != NULL); |
| 5690 ASSERT(current_block()->HasPredecessor()); | 5714 ASSERT(current_block()->HasPredecessor()); |
| 5691 ZoneList<Expression*>* subexprs = expr->values(); | 5715 ZoneList<Expression*>* subexprs = expr->values(); |
| 5692 int length = subexprs->length(); | 5716 int length = subexprs->length(); |
| 5693 HValue* context = environment()->LookupContext(); | 5717 HValue* context = environment()->LookupContext(); |
| 5694 HInstruction* literal; | 5718 HInstruction* literal; |
| 5695 | 5719 |
| 5720 AllocationSiteMode mode = FLAG_track_allocation_sites && !IsOneTimeCode() |
| 5721 ? TRACK_ALLOCATION_SITE |
| 5722 : DONT_TRACK_ALLOCATION_SITE; |
| 5723 |
| 5696 Handle<FixedArray> literals(environment()->closure()->literals()); | 5724 Handle<FixedArray> literals(environment()->closure()->literals()); |
| 5697 Handle<Object> raw_boilerplate(literals->get(expr->literal_index())); | 5725 Handle<Object> raw_boilerplate(literals->get(expr->literal_index())); |
| 5698 | |
| 5699 if (raw_boilerplate->IsUndefined()) { | 5726 if (raw_boilerplate->IsUndefined()) { |
| 5700 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( | 5727 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( |
| 5701 isolate(), literals, expr->constant_elements()); | 5728 isolate(), literals, expr->constant_elements()); |
| 5702 if (raw_boilerplate.is_null()) { | 5729 if (raw_boilerplate.is_null()) { |
| 5703 return Bailout("array boilerplate creation failed"); | 5730 return Bailout("array boilerplate creation failed"); |
| 5704 } | 5731 } |
| 5705 literals->set(expr->literal_index(), *raw_boilerplate); | 5732 literals->set(expr->literal_index(), *raw_boilerplate); |
| 5706 if (JSObject::cast(*raw_boilerplate)->elements()->map() == | 5733 if (JSObject::cast(*raw_boilerplate)->elements()->map() == |
| 5707 isolate()->heap()->fixed_cow_array_map()) { | 5734 isolate()->heap()->fixed_cow_array_map()) { |
| 5708 isolate()->counters()->cow_arrays_created_runtime()->Increment(); | 5735 isolate()->counters()->cow_arrays_created_runtime()->Increment(); |
| 5709 } | 5736 } |
| 5710 } | 5737 } |
| 5711 | 5738 |
| 5712 Handle<JSObject> boilerplate = Handle<JSObject>::cast(raw_boilerplate); | 5739 Handle<JSObject> original_boilerplate = |
| 5740 Handle<JSObject>::cast(raw_boilerplate); |
| 5713 ElementsKind boilerplate_elements_kind = | 5741 ElementsKind boilerplate_elements_kind = |
| 5714 Handle<JSObject>::cast(boilerplate)->GetElementsKind(); | 5742 original_boilerplate->GetElementsKind(); |
| 5715 | |
| 5716 // TODO(mvstanton): This heuristic is only a temporary solution. In the | |
| 5717 // end, we want to quit creating allocation site info after a certain number | |
| 5718 // of GCs for a call site. | |
| 5719 AllocationSiteMode mode = AllocationSiteInfo::GetMode( | |
| 5720 boilerplate_elements_kind); | |
| 5721 | 5743 |
| 5722 // Check whether to use fast or slow deep-copying for boilerplate. | 5744 // Check whether to use fast or slow deep-copying for boilerplate. |
| 5723 int total_size = 0; | 5745 int total_size = 0; |
| 5724 int max_properties = HFastLiteral::kMaxLiteralProperties; | 5746 int max_properties = HFastLiteral::kMaxLiteralProperties; |
| 5725 if (IsFastLiteral(boilerplate, | 5747 if (IsFastLiteral(original_boilerplate, |
| 5726 HFastLiteral::kMaxLiteralDepth, | 5748 HFastLiteral::kMaxLiteralDepth, |
| 5727 &max_properties, | 5749 &max_properties, |
| 5728 &total_size)) { | 5750 &total_size, |
| 5729 if (mode == TRACK_ALLOCATION_SITE) { | 5751 mode)) { |
| 5730 total_size += AllocationSiteInfo::kSize; | 5752 // Copy the boilerplate to prevent unsavory sharing between fullcodegen and |
| 5731 } | 5753 // crankshaft. |
| 5754 Handle<JSObject> boilerplate = DeepCopy(original_boilerplate); |
| 5732 literal = new(zone()) HFastLiteral(context, | 5755 literal = new(zone()) HFastLiteral(context, |
| 5733 boilerplate, | 5756 boilerplate, |
| 5757 original_boilerplate, |
| 5734 total_size, | 5758 total_size, |
| 5735 expr->literal_index(), | 5759 expr->literal_index(), |
| 5736 expr->depth(), | 5760 expr->depth(), |
| 5737 mode); | 5761 mode); |
| 5738 } else { | 5762 } else { |
| 5739 literal = new(zone()) HArrayLiteral(context, | 5763 literal = new(zone()) HArrayLiteral(context, |
| 5740 boilerplate, | 5764 original_boilerplate, |
| 5741 length, | 5765 length, |
| 5742 expr->literal_index(), | 5766 expr->literal_index(), |
| 5743 expr->depth(), | 5767 expr->depth(), |
| 5744 mode); | 5768 mode); |
| 5745 } | 5769 } |
| 5746 | 5770 |
| 5747 // The array is expected in the bailout environment during computation | 5771 // The array is expected in the bailout environment during computation |
| 5748 // of the property values and is the value of the entire expression. | 5772 // of the property values and is the value of the entire expression. |
| 5749 PushAndAdd(literal); | 5773 PushAndAdd(literal); |
| 5750 | 5774 |
| (...skipping 4871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10622 } | 10646 } |
| 10623 } | 10647 } |
| 10624 | 10648 |
| 10625 #ifdef DEBUG | 10649 #ifdef DEBUG |
| 10626 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 10650 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 10627 if (allocator_ != NULL) allocator_->Verify(); | 10651 if (allocator_ != NULL) allocator_->Verify(); |
| 10628 #endif | 10652 #endif |
| 10629 } | 10653 } |
| 10630 | 10654 |
| 10631 } } // namespace v8::internal | 10655 } } // namespace v8::internal |
| OLD | NEW |