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

Side by Side Diff: src/hydrogen.cc

Issue 726423002: Hydrogen should recognize literal smi arrays as fast literals. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Test failure revealed forgotten requirement with dependencies. Created 6 years, 1 month 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 | « no previous file | src/objects.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 <sstream> 7 #include <sstream>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 5511 matching lines...) Expand 10 before | Expand all | Expand 10 after
5522 return false; 5522 return false;
5523 } 5523 }
5524 5524
5525 DCHECK(max_depth >= 0 && *max_properties >= 0); 5525 DCHECK(max_depth >= 0 && *max_properties >= 0);
5526 if (max_depth == 0) return false; 5526 if (max_depth == 0) return false;
5527 5527
5528 Isolate* isolate = boilerplate->GetIsolate(); 5528 Isolate* isolate = boilerplate->GetIsolate();
5529 Handle<FixedArrayBase> elements(boilerplate->elements()); 5529 Handle<FixedArrayBase> elements(boilerplate->elements());
5530 if (elements->length() > 0 && 5530 if (elements->length() > 0 &&
5531 elements->map() != isolate->heap()->fixed_cow_array_map()) { 5531 elements->map() != isolate->heap()->fixed_cow_array_map()) {
5532 if (boilerplate->HasFastObjectElements()) { 5532 if (boilerplate->HasFastSmiOrObjectElements()) {
5533 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 5533 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
5534 int length = elements->length(); 5534 int length = elements->length();
5535 for (int i = 0; i < length; i++) { 5535 for (int i = 0; i < length; i++) {
5536 if ((*max_properties)-- == 0) return false; 5536 if ((*max_properties)-- == 0) return false;
5537 Handle<Object> value(fast_elements->get(i), isolate); 5537 Handle<Object> value(fast_elements->get(i), isolate);
5538 if (value->IsJSObject()) { 5538 if (value->IsJSObject()) {
5539 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 5539 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
5540 if (!IsFastLiteral(value_object, 5540 if (!IsFastLiteral(value_object,
5541 max_depth - 1, 5541 max_depth - 1,
5542 max_properties)) { 5542 max_properties)) {
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
5783 int flags = expr->depth() == 1 5783 int flags = expr->depth() == 1
5784 ? ArrayLiteral::kShallowElements 5784 ? ArrayLiteral::kShallowElements
5785 : ArrayLiteral::kNoFlags; 5785 : ArrayLiteral::kNoFlags;
5786 flags |= ArrayLiteral::kDisableMementos; 5786 flags |= ArrayLiteral::kDisableMementos;
5787 5787
5788 Add<HPushArguments>(Add<HConstant>(literals), 5788 Add<HPushArguments>(Add<HConstant>(literals),
5789 Add<HConstant>(literal_index), 5789 Add<HConstant>(literal_index),
5790 Add<HConstant>(constants), 5790 Add<HConstant>(constants),
5791 Add<HConstant>(flags)); 5791 Add<HConstant>(flags));
5792 5792
5793 // TODO(mvstanton): Consider a flag to turn off creation of any
5794 // AllocationMementos for this call: we are in crankshaft and should have
5795 // learned enough about transition behavior to stop emitting mementos.
5796 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral; 5793 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral;
5797 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), 5794 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
5798 Runtime::FunctionForId(function_id), 5795 Runtime::FunctionForId(function_id),
5799 4); 5796 4);
5800 5797
5801 // De-opt if elements kind changed from boilerplate_elements_kind. 5798 // Register to deopt if the boilerplate ElementsKind changes.
5802 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); 5799 AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info());
5803 literal = Add<HCheckMaps>(literal, map);
5804 } 5800 }
5805 5801
5806 // The array is expected in the bailout environment during computation 5802 // The array is expected in the bailout environment during computation
5807 // of the property values and is the value of the entire expression. 5803 // of the property values and is the value of the entire expression.
5808 Push(literal); 5804 Push(literal);
5809 // The literal index is on the stack, too. 5805 // The literal index is on the stack, too.
5810 Push(Add<HConstant>(expr->literal_index())); 5806 Push(Add<HConstant>(expr->literal_index()));
5811 5807
5812 HInstruction* elements = NULL; 5808 HInstruction* elements = NULL;
5813 5809
(...skipping 3528 matching lines...) Expand 10 before | Expand all | Expand 10 after
9342 int argument_count, 9338 int argument_count,
9343 Handle<AllocationSite> site) { 9339 Handle<AllocationSite> site) {
9344 DCHECK(!site.is_null()); 9340 DCHECK(!site.is_null());
9345 DCHECK(argument_count >= 0 && argument_count <= 1); 9341 DCHECK(argument_count >= 0 && argument_count <= 1);
9346 NoObservableSideEffectsScope no_effects(this); 9342 NoObservableSideEffectsScope no_effects(this);
9347 9343
9348 // We should at least have the constructor on the expression stack. 9344 // We should at least have the constructor on the expression stack.
9349 HValue* constructor = environment()->ExpressionStackAt(argument_count); 9345 HValue* constructor = environment()->ExpressionStackAt(argument_count);
9350 9346
9351 // Register on the site for deoptimization if the transition feedback changes. 9347 // Register on the site for deoptimization if the transition feedback changes.
9352 AllocationSite::AddDependentCompilationInfo( 9348 AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info());
9353 site, AllocationSite::TRANSITIONS, top_info());
9354 ElementsKind kind = site->GetElementsKind(); 9349 ElementsKind kind = site->GetElementsKind();
9355 HInstruction* site_instruction = Add<HConstant>(site); 9350 HInstruction* site_instruction = Add<HConstant>(site);
9356 9351
9357 // In the single constant argument case, we may have to adjust elements kind 9352 // In the single constant argument case, we may have to adjust elements kind
9358 // to avoid creating a packed non-empty array. 9353 // to avoid creating a packed non-empty array.
9359 if (argument_count == 1 && !IsHoleyElementsKind(kind)) { 9354 if (argument_count == 1 && !IsHoleyElementsKind(kind)) {
9360 HValue* argument = environment()->Top(); 9355 HValue* argument = environment()->Top();
9361 if (argument->IsConstant()) { 9356 if (argument->IsConstant()) {
9362 HConstant* constant_argument = HConstant::cast(argument); 9357 HConstant* constant_argument = HConstant::cast(argument);
9363 DCHECK(constant_argument->HasSmiValue()); 9358 DCHECK(constant_argument->HasSmiValue());
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
9473 9468
9474 // Allocate an instance of the implicit receiver object. 9469 // Allocate an instance of the implicit receiver object.
9475 HValue* size_in_bytes = Add<HConstant>(instance_size); 9470 HValue* size_in_bytes = Add<HConstant>(instance_size);
9476 HAllocationMode allocation_mode; 9471 HAllocationMode allocation_mode;
9477 if (FLAG_pretenuring_call_new) { 9472 if (FLAG_pretenuring_call_new) {
9478 if (FLAG_allocation_site_pretenuring) { 9473 if (FLAG_allocation_site_pretenuring) {
9479 // Try to use pretenuring feedback. 9474 // Try to use pretenuring feedback.
9480 Handle<AllocationSite> allocation_site = expr->allocation_site(); 9475 Handle<AllocationSite> allocation_site = expr->allocation_site();
9481 allocation_mode = HAllocationMode(allocation_site); 9476 allocation_mode = HAllocationMode(allocation_site);
9482 // Take a dependency on allocation site. 9477 // Take a dependency on allocation site.
9483 AllocationSite::AddDependentCompilationInfo(allocation_site, 9478 AllocationSite::RegisterForDeoptOnTenureChange(allocation_site,
9484 AllocationSite::TENURING, 9479 top_info());
9485 top_info());
9486 } 9480 }
9487 } 9481 }
9488 9482
9489 HAllocate* receiver = BuildAllocate( 9483 HAllocate* receiver = BuildAllocate(
9490 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode); 9484 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode);
9491 receiver->set_known_initial_map(initial_map); 9485 receiver->set_known_initial_map(initial_map);
9492 9486
9493 // Initialize map and fields of the newly allocated object. 9487 // Initialize map and fields of the newly allocated object.
9494 { NoObservableSideEffectsScope no_effects(this); 9488 { NoObservableSideEffectsScope no_effects(this);
9495 DCHECK(initial_map->instance_type() == JS_OBJECT_TYPE); 9489 DCHECK(initial_map->instance_type() == JS_OBJECT_TYPE);
(...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after
10518 if (right->IsConstant() && 10512 if (right->IsConstant() &&
10519 HConstant::cast(right)->HasStringValue() && 10513 HConstant::cast(right)->HasStringValue() &&
10520 HConstant::cast(right)->StringValue()->length() == 0) { 10514 HConstant::cast(right)->StringValue()->length() == 0) {
10521 return left; 10515 return left;
10522 } 10516 }
10523 10517
10524 // Register the dependent code with the allocation site. 10518 // Register the dependent code with the allocation site.
10525 if (!allocation_mode.feedback_site().is_null()) { 10519 if (!allocation_mode.feedback_site().is_null()) {
10526 DCHECK(!graph()->info()->IsStub()); 10520 DCHECK(!graph()->info()->IsStub());
10527 Handle<AllocationSite> site(allocation_mode.feedback_site()); 10521 Handle<AllocationSite> site(allocation_mode.feedback_site());
10528 AllocationSite::AddDependentCompilationInfo( 10522 AllocationSite::RegisterForDeoptOnTenureChange(site, top_info());
10529 site, AllocationSite::TENURING, top_info());
10530 } 10523 }
10531 10524
10532 // Inline the string addition into the stub when creating allocation 10525 // Inline the string addition into the stub when creating allocation
10533 // mementos to gather allocation site feedback, or if we can statically 10526 // mementos to gather allocation site feedback, or if we can statically
10534 // infer that we're going to create a cons string. 10527 // infer that we're going to create a cons string.
10535 if ((graph()->info()->IsStub() && 10528 if ((graph()->info()->IsStub() &&
10536 allocation_mode.CreateAllocationMementos()) || 10529 allocation_mode.CreateAllocationMementos()) ||
10537 (left->IsConstant() && 10530 (left->IsConstant() &&
10538 HConstant::cast(left)->HasStringValue() && 10531 HConstant::cast(left)->HasStringValue() &&
10539 HConstant::cast(left)->StringValue()->length() + 1 >= 10532 HConstant::cast(left)->StringValue()->length() + 1 >=
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
11114 NoObservableSideEffectsScope no_effects(this); 11107 NoObservableSideEffectsScope no_effects(this);
11115 InstanceType instance_type = boilerplate_object->map()->instance_type(); 11108 InstanceType instance_type = boilerplate_object->map()->instance_type();
11116 DCHECK(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); 11109 DCHECK(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE);
11117 11110
11118 HType type = instance_type == JS_ARRAY_TYPE 11111 HType type = instance_type == JS_ARRAY_TYPE
11119 ? HType::JSArray() : HType::JSObject(); 11112 ? HType::JSArray() : HType::JSObject();
11120 HValue* object_size_constant = Add<HConstant>( 11113 HValue* object_size_constant = Add<HConstant>(
11121 boilerplate_object->map()->instance_size()); 11114 boilerplate_object->map()->instance_size());
11122 11115
11123 PretenureFlag pretenure_flag = NOT_TENURED; 11116 PretenureFlag pretenure_flag = NOT_TENURED;
11117 Handle<AllocationSite> site(site_context->current());
11124 if (FLAG_allocation_site_pretenuring) { 11118 if (FLAG_allocation_site_pretenuring) {
11125 pretenure_flag = site_context->current()->GetPretenureMode(); 11119 pretenure_flag = site_context->current()->GetPretenureMode();
11126 Handle<AllocationSite> site(site_context->current()); 11120 AllocationSite::RegisterForDeoptOnTenureChange(site, top_info());
11127 AllocationSite::AddDependentCompilationInfo(
11128 site, AllocationSite::TENURING, top_info());
11129 } 11121 }
11130 11122
11123 AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info());
11124
11131 HInstruction* object = Add<HAllocate>(object_size_constant, type, 11125 HInstruction* object = Add<HAllocate>(object_size_constant, type,
11132 pretenure_flag, instance_type, site_context->current()); 11126 pretenure_flag, instance_type, site_context->current());
11133 11127
11134 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the 11128 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the
11135 // elements array may not get folded into the object. Hence, we set the 11129 // elements array may not get folded into the object. Hence, we set the
11136 // elements pointer to empty fixed array and let store elimination remove 11130 // elements pointer to empty fixed array and let store elimination remove
11137 // this store in the folding case. 11131 // this store in the folding case.
11138 HConstant* empty_fixed_array = Add<HConstant>( 11132 HConstant* empty_fixed_array = Add<HConstant>(
11139 isolate()->factory()->empty_fixed_array()); 11133 isolate()->factory()->empty_fixed_array());
11140 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 11134 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
(...skipping 1598 matching lines...) Expand 10 before | Expand all | Expand 10 after
12739 if (ShouldProduceTraceOutput()) { 12733 if (ShouldProduceTraceOutput()) {
12740 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12734 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12741 } 12735 }
12742 12736
12743 #ifdef DEBUG 12737 #ifdef DEBUG
12744 graph_->Verify(false); // No full verify. 12738 graph_->Verify(false); // No full verify.
12745 #endif 12739 #endif
12746 } 12740 }
12747 12741
12748 } } // namespace v8::internal 12742 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698