Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: src/hydrogen.cc

Issue 12114054: Supporting AllocationSiteInfo for Nested arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Some updates Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698