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

Side by Side Diff: src/hydrogen.cc

Issue 282093009: Emit mementos in crankshaft. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE. Created 6 years, 6 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
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/hydrogen.h" 5 #include "src/hydrogen.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 #include "src/allocation-site-scopes.h" 10 #include "src/allocation-site-scopes.h"
(...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after
1746 1746
1747 1747
1748 HAllocate* HGraphBuilder::BuildAllocate( 1748 HAllocate* HGraphBuilder::BuildAllocate(
1749 HValue* object_size, 1749 HValue* object_size,
1750 HType type, 1750 HType type,
1751 InstanceType instance_type, 1751 InstanceType instance_type,
1752 HAllocationMode allocation_mode) { 1752 HAllocationMode allocation_mode) {
1753 // Compute the effective allocation size. 1753 // Compute the effective allocation size.
1754 HValue* size = object_size; 1754 HValue* size = object_size;
1755 if (allocation_mode.CreateAllocationMementos()) { 1755 if (allocation_mode.CreateAllocationMementos()) {
1756 size = AddUncasted<HAdd>(size, Add<HConstant>(AllocationMemento::kSize)); 1756 NoObservableSideEffectsScope no_effects(this);
1757 size = AddInstruction(
1758 HAdd::New(zone(), context(), object_size,
1759 Add<HConstant>(AllocationMemento::kSize)));
1757 size->ClearFlag(HValue::kCanOverflow); 1760 size->ClearFlag(HValue::kCanOverflow);
1758 } 1761 }
1759 1762
1760 // Perform the actual allocation. 1763 // Perform the actual allocation.
1761 HAllocate* object = Add<HAllocate>( 1764 HAllocate* object = Add<HAllocate>(
1762 size, type, allocation_mode.GetPretenureMode(), 1765 size, type, allocation_mode.GetPretenureMode(),
1763 instance_type, allocation_mode.feedback_site()); 1766 instance_type, allocation_mode.feedback_site());
1764 1767
1765 // Setup the allocation memento. 1768 // Setup the allocation memento.
1766 if (allocation_mode.CreateAllocationMementos()) { 1769 if (allocation_mode.CreateAllocationMementos()) {
(...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after
2791 } 2794 }
2792 2795
2793 if_nil.CaptureContinuation(continuation); 2796 if_nil.CaptureContinuation(continuation);
2794 } 2797 }
2795 2798
2796 2799
2797 void HGraphBuilder::BuildCreateAllocationMemento( 2800 void HGraphBuilder::BuildCreateAllocationMemento(
2798 HValue* previous_object, 2801 HValue* previous_object,
2799 HValue* previous_object_size, 2802 HValue* previous_object_size,
2800 HValue* allocation_site) { 2803 HValue* allocation_site) {
2804 NoObservableSideEffectsScope no_effects(this);
2801 ASSERT(allocation_site != NULL); 2805 ASSERT(allocation_site != NULL);
2802 HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>( 2806 HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>(
2803 previous_object, previous_object_size, HType::HeapObject()); 2807 previous_object, previous_object_size, HType::HeapObject());
2804 AddStoreMapConstant( 2808 AddStoreMapConstant(
2805 allocation_memento, isolate()->factory()->allocation_memento_map()); 2809 allocation_memento, isolate()->factory()->allocation_memento_map());
2806 Add<HStoreNamedField>( 2810 Add<HStoreNamedField>(
2807 allocation_memento, 2811 allocation_memento,
2808 HObjectAccess::ForAllocationMementoSite(), 2812 HObjectAccess::ForAllocationMementoSite(),
2809 allocation_site); 2813 allocation_site);
2810 if (FLAG_allocation_site_pretenuring) { 2814 if (FLAG_allocation_site_pretenuring) {
(...skipping 2346 matching lines...) Expand 10 before | Expand all | Expand 10 after
5157 Handle<JSObject> boilerplate; 5161 Handle<JSObject> boilerplate;
5158 if (!literals_cell->IsUndefined()) { 5162 if (!literals_cell->IsUndefined()) {
5159 // Retrieve the boilerplate 5163 // Retrieve the boilerplate
5160 site = Handle<AllocationSite>::cast(literals_cell); 5164 site = Handle<AllocationSite>::cast(literals_cell);
5161 boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()), 5165 boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()),
5162 isolate()); 5166 isolate());
5163 } 5167 }
5164 5168
5165 if (!boilerplate.is_null() && 5169 if (!boilerplate.is_null() &&
5166 IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) { 5170 IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) {
5167 AllocationSiteUsageContext usage_context(isolate(), site, false); 5171 bool emit_mementos = FLAG_allocation_site_pretenuring &&
5172 site->emit_mementos();
5173 AllocationSiteUsageContext usage_context(isolate(), site, emit_mementos);
5168 usage_context.EnterNewScope(); 5174 usage_context.EnterNewScope();
5169 literal = BuildFastLiteral(boilerplate, &usage_context); 5175 literal = BuildFastLiteral(boilerplate, &usage_context);
5170 usage_context.ExitScope(site, boilerplate); 5176 usage_context.ExitScope(site, boilerplate);
5171 } else { 5177 } else {
5172 NoObservableSideEffectsScope no_effects(this); 5178 NoObservableSideEffectsScope no_effects(this);
5173 Handle<FixedArray> closure_literals(closure->literals(), isolate()); 5179 Handle<FixedArray> closure_literals(closure->literals(), isolate());
5174 Handle<FixedArray> constant_properties = expr->constant_properties(); 5180 Handle<FixedArray> constant_properties = expr->constant_properties();
5175 int literal_index = expr->literal_index(); 5181 int literal_index = expr->literal_index();
5176 int flags = expr->fast_elements() 5182 int flags = expr->fast_elements()
5177 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; 5183 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags;
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
5314 ASSERT(site->SitePointsToLiteral()); 5320 ASSERT(site->SitePointsToLiteral());
5315 5321
5316 ElementsKind boilerplate_elements_kind = 5322 ElementsKind boilerplate_elements_kind =
5317 boilerplate_object->GetElementsKind(); 5323 boilerplate_object->GetElementsKind();
5318 5324
5319 // Check whether to use fast or slow deep-copying for boilerplate. 5325 // Check whether to use fast or slow deep-copying for boilerplate.
5320 int max_properties = kMaxFastLiteralProperties; 5326 int max_properties = kMaxFastLiteralProperties;
5321 if (IsFastLiteral(boilerplate_object, 5327 if (IsFastLiteral(boilerplate_object,
5322 kMaxFastLiteralDepth, 5328 kMaxFastLiteralDepth,
5323 &max_properties)) { 5329 &max_properties)) {
5324 AllocationSiteUsageContext usage_context(isolate(), site, false); 5330 bool emit_mementos = FLAG_allocation_site_pretenuring &&
5331 site->emit_mementos();
5332 AllocationSiteUsageContext usage_context(isolate(), site, emit_mementos);
5325 usage_context.EnterNewScope(); 5333 usage_context.EnterNewScope();
5326 literal = BuildFastLiteral(boilerplate_object, &usage_context); 5334 literal = BuildFastLiteral(boilerplate_object, &usage_context);
5327 usage_context.ExitScope(site, boilerplate_object); 5335 usage_context.ExitScope(site, boilerplate_object);
5328 } else { 5336 } else {
5329 NoObservableSideEffectsScope no_effects(this); 5337 NoObservableSideEffectsScope no_effects(this);
5330 // Boilerplate already exists and constant elements are never accessed, 5338 // Boilerplate already exists and constant elements are never accessed,
5331 // pass an empty fixed array to the runtime function instead. 5339 // pass an empty fixed array to the runtime function instead.
5332 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); 5340 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array();
5333 int literal_index = expr->literal_index(); 5341 int literal_index = expr->literal_index();
5334 int flags = expr->depth() == 1 5342 int flags = expr->depth() == 1
(...skipping 2985 matching lines...) Expand 10 before | Expand all | Expand 10 after
8320 target->context()->global_object()->global_receiver()); 8328 target->context()->global_object()->global_receiver());
8321 return Add<HConstant>(global_receiver); 8329 return Add<HConstant>(global_receiver);
8322 } 8330 }
8323 return graph()->GetConstantUndefined(); 8331 return graph()->GetConstantUndefined();
8324 } 8332 }
8325 8333
8326 8334
8327 void HOptimizedGraphBuilder::BuildArrayCall(Expression* expression, 8335 void HOptimizedGraphBuilder::BuildArrayCall(Expression* expression,
8328 int arguments_count, 8336 int arguments_count,
8329 HValue* function, 8337 HValue* function,
8330 Handle<AllocationSite> site) { 8338 Handle<AllocationSite> site,
8339 HAllocationMode mode) {
8331 Add<HCheckValue>(function, array_function()); 8340 Add<HCheckValue>(function, array_function());
8332 8341
8333 if (IsCallArrayInlineable(arguments_count, site)) { 8342 if (IsCallArrayInlineable(arguments_count, site)) {
8334 BuildInlinedCallArray(expression, arguments_count, site); 8343 BuildInlinedCallArray(expression, arguments_count, mode, site);
8335 return; 8344 return;
8336 } 8345 }
8337 8346
8338 HInstruction* call = PreProcessCall(New<HCallNewArray>( 8347 HInstruction* call = PreProcessCall(New<HCallNewArray>(
8339 function, arguments_count + 1, site->GetElementsKind())); 8348 function, arguments_count + 1, site->GetElementsKind(), mode));
8340 if (expression->IsCall()) { 8349 if (expression->IsCall()) {
8341 Drop(1); 8350 Drop(1);
8342 } 8351 }
8343 ast_context()->ReturnInstruction(call, expression->id()); 8352 ast_context()->ReturnInstruction(call, expression->id());
8344 } 8353 }
8345 8354
8346 8355
8347 HValue* HOptimizedGraphBuilder::BuildArrayIndexOf(HValue* receiver, 8356 HValue* HOptimizedGraphBuilder::BuildArrayIndexOf(HValue* receiver,
8348 HValue* search_element, 8357 HValue* search_element,
8349 ElementsKind kind, 8358 ElementsKind kind,
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
8490 if (!array_function().is_identical_to(expr->target())) { 8499 if (!array_function().is_identical_to(expr->target())) {
8491 return false; 8500 return false;
8492 } 8501 }
8493 8502
8494 Handle<AllocationSite> site = expr->allocation_site(); 8503 Handle<AllocationSite> site = expr->allocation_site();
8495 if (site.is_null()) return false; 8504 if (site.is_null()) return false;
8496 8505
8497 BuildArrayCall(expr, 8506 BuildArrayCall(expr,
8498 expr->arguments()->length(), 8507 expr->arguments()->length(),
8499 function, 8508 function,
8500 site); 8509 site,
8510 HAllocationMode());
8501 return true; 8511 return true;
8502 } 8512 }
8503 8513
8504 8514
8505 bool HOptimizedGraphBuilder::TryHandleArrayCallNew(CallNew* expr, 8515 bool HOptimizedGraphBuilder::TryHandleArrayCallNew(CallNew* expr,
8506 HValue* function) { 8516 HValue* function,
8517 HAllocationMode mode) {
8507 if (!array_function().is_identical_to(expr->target())) { 8518 if (!array_function().is_identical_to(expr->target())) {
8508 return false; 8519 return false;
8509 } 8520 }
8510 8521
8511 BuildArrayCall(expr, 8522 BuildArrayCall(expr,
8512 expr->arguments()->length(), 8523 expr->arguments()->length(),
8513 function, 8524 function,
8514 expr->allocation_site()); 8525 expr->allocation_site(),
8526 mode);
8515 return true; 8527 return true;
8516 } 8528 }
8517 8529
8518 8530
8519 void HOptimizedGraphBuilder::VisitCall(Call* expr) { 8531 void HOptimizedGraphBuilder::VisitCall(Call* expr) {
8520 ASSERT(!HasStackOverflow()); 8532 ASSERT(!HasStackOverflow());
8521 ASSERT(current_block() != NULL); 8533 ASSERT(current_block() != NULL);
8522 ASSERT(current_block()->HasPredecessor()); 8534 ASSERT(current_block()->HasPredecessor());
8523 Expression* callee = expr->expression(); 8535 Expression* callee = expr->expression();
8524 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 8536 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
8690 } 8702 }
8691 8703
8692 Drop(1); // Drop the function. 8704 Drop(1); // Drop the function.
8693 return ast_context()->ReturnInstruction(call, expr->id()); 8705 return ast_context()->ReturnInstruction(call, expr->id());
8694 } 8706 }
8695 8707
8696 8708
8697 void HOptimizedGraphBuilder::BuildInlinedCallArray( 8709 void HOptimizedGraphBuilder::BuildInlinedCallArray(
8698 Expression* expression, 8710 Expression* expression,
8699 int argument_count, 8711 int argument_count,
8712 HAllocationMode mode,
8700 Handle<AllocationSite> site) { 8713 Handle<AllocationSite> site) {
8701 ASSERT(!site.is_null()); 8714 ASSERT(!site.is_null());
8702 ASSERT(argument_count >= 0 && argument_count <= 1); 8715 ASSERT(argument_count >= 0 && argument_count <= 1);
8703 NoObservableSideEffectsScope no_effects(this); 8716 NoObservableSideEffectsScope no_effects(this);
8704 8717
8705 // We should at least have the constructor on the expression stack. 8718 // We should at least have the constructor on the expression stack.
8706 HValue* constructor = environment()->ExpressionStackAt(argument_count); 8719 HValue* constructor = environment()->ExpressionStackAt(argument_count);
8707 8720
8708 // Register on the site for deoptimization if the transition feedback changes. 8721 // Register on the site for deoptimization if the transition feedback changes.
8709 AllocationSite::AddDependentCompilationInfo( 8722 AllocationSite::AddDependentCompilationInfo(
8710 site, AllocationSite::TRANSITIONS, top_info()); 8723 site, AllocationSite::TRANSITIONS, top_info());
8711 ElementsKind kind = site->GetElementsKind(); 8724 ElementsKind kind = site->GetElementsKind();
8712 HInstruction* site_instruction = Add<HConstant>(site); 8725 HInstruction* site_instruction = Add<HConstant>(site);
8713 8726
8714 // In the single constant argument case, we may have to adjust elements kind 8727 // In the single constant argument case, we may have to adjust elements kind
8715 // to avoid creating a packed non-empty array. 8728 // to avoid creating a packed non-empty array.
8716 if (argument_count == 1 && !IsHoleyElementsKind(kind)) { 8729 if (argument_count == 1 && !IsHoleyElementsKind(kind)) {
8717 HValue* argument = environment()->Top(); 8730 HValue* argument = environment()->Top();
8718 if (argument->IsConstant()) { 8731 if (argument->IsConstant()) {
8719 HConstant* constant_argument = HConstant::cast(argument); 8732 HConstant* constant_argument = HConstant::cast(argument);
8720 ASSERT(constant_argument->HasSmiValue()); 8733 ASSERT(constant_argument->HasSmiValue());
8721 int constant_array_size = constant_argument->Integer32Value(); 8734 int constant_array_size = constant_argument->Integer32Value();
8722 if (constant_array_size != 0) { 8735 if (constant_array_size != 0) {
8723 kind = GetHoleyElementsKind(kind); 8736 kind = GetHoleyElementsKind(kind);
8724 } 8737 }
8725 } 8738 }
8726 } 8739 }
8727 8740
8728 // Build the array. 8741 // Build the array. Should we emit mementos?
8742 AllocationSiteOverrideMode site_mode = mode.CreateAllocationMementos()
8743 ? DONT_OVERRIDE
8744 : DISABLE_ALLOCATION_SITES;
8745
8729 JSArrayBuilder array_builder(this, 8746 JSArrayBuilder array_builder(this,
8730 kind, 8747 kind,
8731 site_instruction, 8748 site_instruction,
8732 constructor, 8749 constructor,
8733 DISABLE_ALLOCATION_SITES); 8750 site_mode);
8751
8734 HValue* new_object = argument_count == 0 8752 HValue* new_object = argument_count == 0
8735 ? array_builder.AllocateEmptyArray() 8753 ? array_builder.AllocateEmptyArray()
8736 : BuildAllocateArrayFromLength(&array_builder, Top()); 8754 : BuildAllocateArrayFromLength(&array_builder, Top());
8737 8755
8738 int args_to_drop = argument_count + (expression->IsCall() ? 2 : 1); 8756 int args_to_drop = argument_count + (expression->IsCall() ? 2 : 1);
8739 Drop(args_to_drop); 8757 Drop(args_to_drop);
8740 ast_context()->ReturnValue(new_object); 8758 ast_context()->ReturnValue(new_object);
8741 } 8759 }
8742 8760
8743 8761
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
8789 TraceInline(target, caller, "AllocationSite requested no inlining."); 8807 TraceInline(target, caller, "AllocationSite requested no inlining.");
8790 } 8808 }
8791 8809
8792 if (inline_ok) { 8810 if (inline_ok) {
8793 TraceInline(target, caller, NULL); 8811 TraceInline(target, caller, NULL);
8794 } 8812 }
8795 return inline_ok; 8813 return inline_ok;
8796 } 8814 }
8797 8815
8798 8816
8817 void HOptimizedGraphBuilder::InitializeAllocationModeForCallNew(
8818 CallNew* expr,
8819 HAllocationMode* mode) {
8820 if (FLAG_pretenuring_call_new) {
8821 if (FLAG_allocation_site_pretenuring) {
8822 Handle<AllocationSite> allocation_site = expr->allocation_site();
8823 HConstant* site_constant = NULL;
8824 // By passing a non-null HConstant AllocationSite to HAllocationMode,
8825 // we ensure that a memento will be emitted.
8826 if (allocation_site->emit_mementos()) {
8827 site_constant = Add<HConstant>(allocation_site);
8828 }
8829 // Try to use pretenuring feedback.
8830 *mode = HAllocationMode(allocation_site, site_constant);
8831 // Take a dependency on allocation site.
8832 AllocationSite::AddDependentCompilationInfo(allocation_site,
8833 AllocationSite::TENURING,
8834 top_info());
8835 }
8836 }
8837 // No else case, the mode will be left at it's default.
8838 }
8839
8840
8799 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { 8841 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
8800 ASSERT(!HasStackOverflow()); 8842 ASSERT(!HasStackOverflow());
8801 ASSERT(current_block() != NULL); 8843 ASSERT(current_block() != NULL);
8802 ASSERT(current_block()->HasPredecessor()); 8844 ASSERT(current_block()->HasPredecessor());
8803 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 8845 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
8804 int argument_count = expr->arguments()->length() + 1; // Plus constructor. 8846 int argument_count = expr->arguments()->length() + 1; // Plus constructor.
8805 Factory* factory = isolate()->factory(); 8847 Factory* factory = isolate()->factory();
8806 8848
8807 // The constructor function is on the stack in the unoptimized code 8849 // The constructor function is on the stack in the unoptimized code
8808 // during evaluation of the arguments. 8850 // during evaluation of the arguments.
(...skipping 15 matching lines...) Expand all
8824 8866
8825 // Calculate instance size from initial map of constructor. 8867 // Calculate instance size from initial map of constructor.
8826 ASSERT(constructor->has_initial_map()); 8868 ASSERT(constructor->has_initial_map());
8827 Handle<Map> initial_map(constructor->initial_map()); 8869 Handle<Map> initial_map(constructor->initial_map());
8828 int instance_size = initial_map->instance_size(); 8870 int instance_size = initial_map->instance_size();
8829 ASSERT(initial_map->InitialPropertiesLength() == 0); 8871 ASSERT(initial_map->InitialPropertiesLength() == 0);
8830 8872
8831 // Allocate an instance of the implicit receiver object. 8873 // Allocate an instance of the implicit receiver object.
8832 HValue* size_in_bytes = Add<HConstant>(instance_size); 8874 HValue* size_in_bytes = Add<HConstant>(instance_size);
8833 HAllocationMode allocation_mode; 8875 HAllocationMode allocation_mode;
8834 if (FLAG_pretenuring_call_new) { 8876 InitializeAllocationModeForCallNew(expr, &allocation_mode);
8835 if (FLAG_allocation_site_pretenuring) {
8836 // Try to use pretenuring feedback.
8837 Handle<AllocationSite> allocation_site = expr->allocation_site();
8838 allocation_mode = HAllocationMode(allocation_site);
8839 // Take a dependency on allocation site.
8840 AllocationSite::AddDependentCompilationInfo(allocation_site,
8841 AllocationSite::TENURING,
8842 top_info());
8843 }
8844 }
8845 8877
8846 HAllocate* receiver = BuildAllocate( 8878 HAllocate* receiver = BuildAllocate(
8847 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode); 8879 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode);
8848 receiver->set_known_initial_map(initial_map); 8880 receiver->set_known_initial_map(initial_map);
8849 8881
8850 // Initialize map and fields of the newly allocated object. 8882 // Initialize map and fields of the newly allocated object.
8851 { NoObservableSideEffectsScope no_effects(this); 8883 { NoObservableSideEffectsScope no_effects(this);
8852 ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE); 8884 ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
8853 Add<HStoreNamedField>(receiver, 8885 Add<HStoreNamedField>(receiver,
8854 HObjectAccess::ForMapAndOffset(initial_map, JSObject::kMapOffset), 8886 HObjectAccess::ForMapAndOffset(initial_map, JSObject::kMapOffset),
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
8886 Map::AddDependentCompilationInfo( 8918 Map::AddDependentCompilationInfo(
8887 initial_map, DependentCode::kInitialMapChangedGroup, top_info()); 8919 initial_map, DependentCode::kInitialMapChangedGroup, top_info());
8888 return; 8920 return;
8889 } 8921 }
8890 8922
8891 // TODO(mstarzinger): For now we remove the previous HAllocate and all 8923 // TODO(mstarzinger): For now we remove the previous HAllocate and all
8892 // corresponding instructions and instead add HPushArguments for the 8924 // corresponding instructions and instead add HPushArguments for the
8893 // arguments in case inlining failed. What we actually should do is for 8925 // arguments in case inlining failed. What we actually should do is for
8894 // inlining to try to build a subgraph without mutating the parent graph. 8926 // inlining to try to build a subgraph without mutating the parent graph.
8895 HInstruction* instr = current_block()->last(); 8927 HInstruction* instr = current_block()->last();
8896 do { 8928
8929 // If we decided to emit a memento for this allocation, we need to
8930 // remember the instruction of the HConstant for the site added
8931 // in InitializeAllocationModeForCallNew().
8932 HValue* delete_to_this_instruction =
8933 allocation_mode.CreateAllocationMementos()
8934 ? allocation_mode.current_site()
8935 : receiver;
8936 ASSERT(delete_to_this_instruction != NULL);
8937 while (instr != delete_to_this_instruction) {
8897 HInstruction* prev_instr = instr->previous(); 8938 HInstruction* prev_instr = instr->previous();
8898 instr->DeleteAndReplaceWith(NULL); 8939 instr->DeleteAndReplaceWith(NULL);
8899 instr = prev_instr; 8940 instr = prev_instr;
8900 } while (instr != check); 8941 }
8942 // initial_map_value->DeleteAndReplaceWith(NULL);
8943 if (delete_to_this_instruction == receiver) {
8944 receiver->DeleteAndReplaceWith(NULL);
8945 }
8946 check->DeleteAndReplaceWith(NULL);
8901 environment()->SetExpressionStackAt(receiver_index, function); 8947 environment()->SetExpressionStackAt(receiver_index, function);
8902 HInstruction* call = 8948 HInstruction* call = PreProcessCall(
8903 PreProcessCall(New<HCallNew>(function, argument_count)); 8949 New<HCallNew>(function, argument_count, allocation_mode));
8904 return ast_context()->ReturnInstruction(call, expr->id()); 8950 return ast_context()->ReturnInstruction(call, expr->id());
8905 } else { 8951 } else {
8952 HAllocationMode allocation_mode;
8953 InitializeAllocationModeForCallNew(expr, &allocation_mode);
8954
8906 // The constructor function is both an operand to the instruction and an 8955 // The constructor function is both an operand to the instruction and an
8907 // argument to the construct call. 8956 // argument to the construct call.
8908 if (TryHandleArrayCallNew(expr, function)) return; 8957 if (TryHandleArrayCallNew(expr, function, allocation_mode)) return;
8909 8958
8910 HInstruction* call = 8959 HInstruction* call =
8911 PreProcessCall(New<HCallNew>(function, argument_count)); 8960 PreProcessCall(New<HCallNew>(function, argument_count,
8961 allocation_mode));
8912 return ast_context()->ReturnInstruction(call, expr->id()); 8962 return ast_context()->ReturnInstruction(call, expr->id());
8913 } 8963 }
8914 } 8964 }
8915 8965
8916 8966
8917 // Support for generating inlined runtime functions. 8967 // Support for generating inlined runtime functions.
8918 8968
8919 // Lookup table for generators for runtime calls that are generated inline. 8969 // Lookup table for generators for runtime calls that are generated inline.
8920 // Elements of the table are member pointers to functions of 8970 // Elements of the table are member pointers to functions of
8921 // HOptimizedGraphBuilder. 8971 // HOptimizedGraphBuilder.
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after
9767 Type* right_type = expr->right()->bounds().lower; 9817 Type* right_type = expr->right()->bounds().lower;
9768 Type* result_type = expr->bounds().lower; 9818 Type* result_type = expr->bounds().lower;
9769 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); 9819 Maybe<int> fixed_right_arg = expr->fixed_right_arg();
9770 Handle<AllocationSite> allocation_site = expr->allocation_site(); 9820 Handle<AllocationSite> allocation_site = expr->allocation_site();
9771 9821
9772 HAllocationMode allocation_mode; 9822 HAllocationMode allocation_mode;
9773 if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) { 9823 if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) {
9774 allocation_mode = HAllocationMode(allocation_site); 9824 allocation_mode = HAllocationMode(allocation_site);
9775 } 9825 }
9776 9826
9827 if (FLAG_allocation_site_pretenuring &&
9828 !allocation_site.is_null() &&
9829 allocation_site->emit_mementos()) {
9830 // This allows crankshaft to continue emitting mementos if a pretenuring
9831 // decision wasn't made yet. A dependency is registered on the site in
9832 // the BuildBinaryOperation call below.
9833 HConstant* site_constant = Add<HConstant>(allocation_site);
9834 allocation_mode = HAllocationMode(allocation_site, site_constant);
9835 }
9836
9777 HValue* result = HGraphBuilder::BuildBinaryOperation( 9837 HValue* result = HGraphBuilder::BuildBinaryOperation(
9778 expr->op(), left, right, left_type, right_type, result_type, 9838 expr->op(), left, right, left_type, right_type, result_type,
9779 fixed_right_arg, allocation_mode); 9839 fixed_right_arg, allocation_mode);
9780 // Add a simulate after instructions with observable side effects, and 9840 // Add a simulate after instructions with observable side effects, and
9781 // after phis, which are the result of BuildBinaryOperation when we 9841 // after phis, which are the result of BuildBinaryOperation when we
9782 // inlined some complex subgraph. 9842 // inlined some complex subgraph.
9783 if (result->HasObservableSideEffects() || result->IsPhi()) { 9843 if (result->HasObservableSideEffects() || result->IsPhi()) {
9784 if (push_sim_result == PUSH_BEFORE_SIMULATE) { 9844 if (push_sim_result == PUSH_BEFORE_SIMULATE) {
9785 Push(result); 9845 Push(result);
9786 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 9846 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
10469 10529
10470 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( 10530 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
10471 Handle<JSObject> boilerplate_object, 10531 Handle<JSObject> boilerplate_object,
10472 AllocationSiteUsageContext* site_context) { 10532 AllocationSiteUsageContext* site_context) {
10473 NoObservableSideEffectsScope no_effects(this); 10533 NoObservableSideEffectsScope no_effects(this);
10474 InstanceType instance_type = boilerplate_object->map()->instance_type(); 10534 InstanceType instance_type = boilerplate_object->map()->instance_type();
10475 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); 10535 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE);
10476 10536
10477 HType type = instance_type == JS_ARRAY_TYPE 10537 HType type = instance_type == JS_ARRAY_TYPE
10478 ? HType::JSArray() : HType::JSObject(); 10538 ? HType::JSArray() : HType::JSObject();
10479 HValue* object_size_constant = Add<HConstant>( 10539 int instance_size = boilerplate_object->map()->instance_size();
10480 boilerplate_object->map()->instance_size()); 10540 bool emit_memento = site_context->ShouldCreateMemento(boilerplate_object);
10541 // Should the object allocation include a manually folded memento?
10542 int alloc_size = emit_memento
10543 ? instance_size + AllocationMemento::kSize
10544 : instance_size;
10545 HValue* alloc_size_constant = Add<HConstant>(alloc_size);
10546 HValue* allocation_site_constant = Add<HConstant>(site_context->current());
10481 10547
10482 PretenureFlag pretenure_flag = NOT_TENURED; 10548 PretenureFlag pretenure_flag = NOT_TENURED;
10483 if (FLAG_allocation_site_pretenuring) { 10549 if (FLAG_allocation_site_pretenuring) {
10484 pretenure_flag = site_context->current()->GetPretenureMode(); 10550 pretenure_flag = site_context->current()->GetPretenureMode();
10485 Handle<AllocationSite> site(site_context->current()); 10551 Handle<AllocationSite> site(site_context->current());
10486 AllocationSite::AddDependentCompilationInfo( 10552 AllocationSite::AddDependentCompilationInfo(
10487 site, AllocationSite::TENURING, top_info()); 10553 site, AllocationSite::TENURING, top_info());
10488 } 10554 }
10489 10555
10490 HInstruction* object = Add<HAllocate>(object_size_constant, type, 10556 HInstruction* object = Add<HAllocate>(alloc_size_constant, type,
10491 pretenure_flag, instance_type, site_context->current()); 10557 pretenure_flag, instance_type, site_context->current());
10492 10558
10493 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the 10559 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the
10494 // elements array may not get folded into the object. Hence, we set the 10560 // elements array may not get folded into the object. Hence, we set the
10495 // elements pointer to empty fixed array and let store elimination remove 10561 // elements pointer to empty fixed array and let store elimination remove
10496 // this store in the folding case. 10562 // this store in the folding case.
10497 HConstant* empty_fixed_array = Add<HConstant>( 10563 HConstant* empty_fixed_array = Add<HConstant>(
10498 isolate()->factory()->empty_fixed_array()); 10564 isolate()->factory()->empty_fixed_array());
10499 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 10565 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
10500 empty_fixed_array); 10566 empty_fixed_array);
10501 10567
10502 BuildEmitObjectHeader(boilerplate_object, object); 10568 BuildEmitObjectHeader(boilerplate_object, object);
10569 if (emit_memento) {
10570 BuildCreateAllocationMemento(object,
10571 Add<HConstant>(instance_size),
10572 allocation_site_constant);
10573 }
10503 10574
10504 Handle<FixedArrayBase> elements(boilerplate_object->elements()); 10575 Handle<FixedArrayBase> elements(boilerplate_object->elements());
10505 int elements_size = (elements->length() > 0 && 10576 int elements_size = (elements->length() > 0 &&
10506 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? 10577 elements->map() != isolate()->heap()->fixed_cow_array_map()) ?
10507 elements->Size() : 0; 10578 elements->Size() : 0;
10508 10579
10509 if (pretenure_flag == TENURED && 10580 if (pretenure_flag == TENURED &&
10510 elements->map() == isolate()->heap()->fixed_cow_array_map() && 10581 elements->map() == isolate()->heap()->fixed_cow_array_map() &&
10511 isolate()->heap()->InNewSpace(*elements)) { 10582 isolate()->heap()->InNewSpace(*elements)) {
10512 // If we would like to pretenure a fixed cow array, we must ensure that the 10583 // If we would like to pretenure a fixed cow array, we must ensure that the
(...skipping 1525 matching lines...) Expand 10 before | Expand all | Expand 10 after
12038 if (ShouldProduceTraceOutput()) { 12109 if (ShouldProduceTraceOutput()) {
12039 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12110 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12040 } 12111 }
12041 12112
12042 #ifdef DEBUG 12113 #ifdef DEBUG
12043 graph_->Verify(false); // No full verify. 12114 graph_->Verify(false); // No full verify.
12044 #endif 12115 #endif
12045 } 12116 }
12046 12117
12047 } } // namespace v8::internal 12118 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698