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

Side by Side Diff: src/hydrogen.cc

Issue 1099473004: Reland "Refactor compilation dependency handling." (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 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
« no previous file with comments | « src/hydrogen.h ('k') | src/lithium.cc » ('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 5378 matching lines...) Expand 10 before | Expand all | Expand 10 after
5389 HObjectAccess::ForContextSlot(lookup.slot_index)); 5389 HObjectAccess::ForContextSlot(lookup.slot_index));
5390 return ast_context()->ReturnInstruction(result, expr->id()); 5390 return ast_context()->ReturnInstruction(result, expr->id());
5391 } 5391 }
5392 } 5392 }
5393 5393
5394 LookupIterator it(global, variable->name(), LookupIterator::OWN); 5394 LookupIterator it(global, variable->name(), LookupIterator::OWN);
5395 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); 5395 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD);
5396 5396
5397 if (type == kUseCell) { 5397 if (type == kUseCell) {
5398 Handle<PropertyCell> cell = it.GetPropertyCell(); 5398 Handle<PropertyCell> cell = it.GetPropertyCell();
5399 PropertyCell::AddDependentCompilationInfo(cell, top_info()); 5399 top_info()->dependencies()->AssumePropertyCell(cell);
5400 if (it.property_details().cell_type() == PropertyCellType::kConstant) { 5400 if (it.property_details().cell_type() == PropertyCellType::kConstant) {
5401 Handle<Object> constant_object(cell->value(), isolate()); 5401 Handle<Object> constant_object(cell->value(), isolate());
5402 if (constant_object->IsConsString()) { 5402 if (constant_object->IsConsString()) {
5403 constant_object = 5403 constant_object =
5404 String::Flatten(Handle<String>::cast(constant_object)); 5404 String::Flatten(Handle<String>::cast(constant_object));
5405 } 5405 }
5406 HConstant* constant = New<HConstant>(constant_object); 5406 HConstant* constant = New<HConstant>(constant_object);
5407 return ast_context()->ReturnInstruction(constant, expr->id()); 5407 return ast_context()->ReturnInstruction(constant, expr->id());
5408 } else { 5408 } else {
5409 HConstant* cell_constant = Add<HConstant>(cell); 5409 HConstant* cell_constant = Add<HConstant>(cell);
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
5770 Add<HConstant>(literal_index), 5770 Add<HConstant>(literal_index),
5771 Add<HConstant>(constants), 5771 Add<HConstant>(constants),
5772 Add<HConstant>(flags)); 5772 Add<HConstant>(flags));
5773 5773
5774 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral; 5774 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral;
5775 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), 5775 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
5776 Runtime::FunctionForId(function_id), 5776 Runtime::FunctionForId(function_id),
5777 4); 5777 4);
5778 5778
5779 // Register to deopt if the boilerplate ElementsKind changes. 5779 // Register to deopt if the boilerplate ElementsKind changes.
5780 AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info()); 5780 top_info()->dependencies()->AssumeTransitionStable(site);
5781 } 5781 }
5782 5782
5783 // The array is expected in the bailout environment during computation 5783 // The array is expected in the bailout environment during computation
5784 // of the property values and is the value of the entire expression. 5784 // of the property values and is the value of the entire expression.
5785 Push(literal); 5785 Push(literal);
5786 // The literal index is on the stack, too. 5786 // The literal index is on the stack, too.
5787 Push(Add<HConstant>(expr->literal_index())); 5787 Push(Add<HConstant>(expr->literal_index()));
5788 5788
5789 HInstruction* elements = NULL; 5789 HInstruction* elements = NULL;
5790 5790
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
6085 } 6085 }
6086 6086
6087 field_maps_.Sort(); 6087 field_maps_.Sort();
6088 DCHECK_EQ(num_field_maps, field_maps_.length()); 6088 DCHECK_EQ(num_field_maps, field_maps_.length());
6089 6089
6090 // Determine field HType from field HeapType. 6090 // Determine field HType from field HeapType.
6091 field_type_ = HType::FromType<HeapType>(field_type); 6091 field_type_ = HType::FromType<HeapType>(field_type);
6092 DCHECK(field_type_.IsHeapObject()); 6092 DCHECK(field_type_.IsHeapObject());
6093 6093
6094 // Add dependency on the map that introduced the field. 6094 // Add dependency on the map that introduced the field.
6095 Map::AddDependentCompilationInfo(GetFieldOwnerFromMap(map), 6095 top_info()->dependencies()->AssumeFieldType(GetFieldOwnerFromMap(map));
6096 DependentCode::kFieldTypeGroup, top_info());
6097 return true; 6096 return true;
6098 } 6097 }
6099 6098
6100 6099
6101 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { 6100 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() {
6102 Handle<Map> map = this->map(); 6101 Handle<Map> map = this->map();
6103 6102
6104 while (map->prototype()->IsJSObject()) { 6103 while (map->prototype()->IsJSObject()) {
6105 holder_ = handle(JSObject::cast(map->prototype())); 6104 holder_ = handle(JSObject::cast(map->prototype()));
6106 if (holder_->map()->is_deprecated()) { 6105 if (holder_->map()->is_deprecated()) {
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
6556 DCHECK(instr->HasObservableSideEffects()); 6555 DCHECK(instr->HasObservableSideEffects());
6557 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6556 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6558 return; 6557 return;
6559 } 6558 }
6560 } 6559 }
6561 6560
6562 LookupIterator it(global, var->name(), LookupIterator::OWN); 6561 LookupIterator it(global, var->name(), LookupIterator::OWN);
6563 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); 6562 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE);
6564 if (type == kUseCell) { 6563 if (type == kUseCell) {
6565 Handle<PropertyCell> cell = it.GetPropertyCell(); 6564 Handle<PropertyCell> cell = it.GetPropertyCell();
6566 PropertyCell::AddDependentCompilationInfo(cell, top_info()); 6565 top_info()->dependencies()->AssumePropertyCell(cell);
6567 if (it.property_details().cell_type() == PropertyCellType::kConstant) { 6566 if (it.property_details().cell_type() == PropertyCellType::kConstant) {
6568 Handle<Object> constant(cell->value(), isolate()); 6567 Handle<Object> constant(cell->value(), isolate());
6569 if (value->IsConstant()) { 6568 if (value->IsConstant()) {
6570 HConstant* c_value = HConstant::cast(value); 6569 HConstant* c_value = HConstant::cast(value);
6571 if (!constant.is_identical_to(c_value->handle(isolate()))) { 6570 if (!constant.is_identical_to(c_value->handle(isolate()))) {
6572 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, 6571 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment,
6573 Deoptimizer::EAGER); 6572 Deoptimizer::EAGER);
6574 } 6573 }
6575 } else { 6574 } else {
6576 HValue* c_constant = Add<HConstant>(constant); 6575 HValue* c_constant = Add<HConstant>(constant);
(...skipping 2773 matching lines...) Expand 10 before | Expand all | Expand 10 after
9350 int argument_count, 9349 int argument_count,
9351 Handle<AllocationSite> site) { 9350 Handle<AllocationSite> site) {
9352 DCHECK(!site.is_null()); 9351 DCHECK(!site.is_null());
9353 DCHECK(argument_count >= 0 && argument_count <= 1); 9352 DCHECK(argument_count >= 0 && argument_count <= 1);
9354 NoObservableSideEffectsScope no_effects(this); 9353 NoObservableSideEffectsScope no_effects(this);
9355 9354
9356 // We should at least have the constructor on the expression stack. 9355 // We should at least have the constructor on the expression stack.
9357 HValue* constructor = environment()->ExpressionStackAt(argument_count); 9356 HValue* constructor = environment()->ExpressionStackAt(argument_count);
9358 9357
9359 // Register on the site for deoptimization if the transition feedback changes. 9358 // Register on the site for deoptimization if the transition feedback changes.
9360 AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info()); 9359 top_info()->dependencies()->AssumeTransitionStable(site);
9361 ElementsKind kind = site->GetElementsKind(); 9360 ElementsKind kind = site->GetElementsKind();
9362 HInstruction* site_instruction = Add<HConstant>(site); 9361 HInstruction* site_instruction = Add<HConstant>(site);
9363 9362
9364 // In the single constant argument case, we may have to adjust elements kind 9363 // In the single constant argument case, we may have to adjust elements kind
9365 // to avoid creating a packed non-empty array. 9364 // to avoid creating a packed non-empty array.
9366 if (argument_count == 1 && !IsHoleyElementsKind(kind)) { 9365 if (argument_count == 1 && !IsHoleyElementsKind(kind)) {
9367 HValue* argument = environment()->Top(); 9366 HValue* argument = environment()->Top();
9368 if (argument->IsConstant()) { 9367 if (argument->IsConstant()) {
9369 HConstant* constant_argument = HConstant::cast(argument); 9368 HConstant* constant_argument = HConstant::cast(argument);
9370 DCHECK(constant_argument->HasSmiValue()); 9369 DCHECK(constant_argument->HasSmiValue());
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
9486 9485
9487 // Allocate an instance of the implicit receiver object. 9486 // Allocate an instance of the implicit receiver object.
9488 HValue* size_in_bytes = Add<HConstant>(instance_size); 9487 HValue* size_in_bytes = Add<HConstant>(instance_size);
9489 HAllocationMode allocation_mode; 9488 HAllocationMode allocation_mode;
9490 if (FLAG_pretenuring_call_new) { 9489 if (FLAG_pretenuring_call_new) {
9491 if (FLAG_allocation_site_pretenuring) { 9490 if (FLAG_allocation_site_pretenuring) {
9492 // Try to use pretenuring feedback. 9491 // Try to use pretenuring feedback.
9493 Handle<AllocationSite> allocation_site = expr->allocation_site(); 9492 Handle<AllocationSite> allocation_site = expr->allocation_site();
9494 allocation_mode = HAllocationMode(allocation_site); 9493 allocation_mode = HAllocationMode(allocation_site);
9495 // Take a dependency on allocation site. 9494 // Take a dependency on allocation site.
9496 AllocationSite::RegisterForDeoptOnTenureChange(allocation_site, 9495 top_info()->dependencies()->AssumeTenuringDecision(allocation_site);
9497 top_info());
9498 } 9496 }
9499 } 9497 }
9500 9498
9501 HAllocate* receiver = BuildAllocate( 9499 HAllocate* receiver = BuildAllocate(
9502 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode); 9500 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode);
9503 receiver->set_known_initial_map(initial_map); 9501 receiver->set_known_initial_map(initial_map);
9504 9502
9505 // Initialize map and fields of the newly allocated object. 9503 // Initialize map and fields of the newly allocated object.
9506 { NoObservableSideEffectsScope no_effects(this); 9504 { NoObservableSideEffectsScope no_effects(this);
9507 DCHECK(initial_map->instance_type() == JS_OBJECT_TYPE); 9505 DCHECK(initial_map->instance_type() == JS_OBJECT_TYPE);
(...skipping 23 matching lines...) Expand all
9531 // Replace the constructor function with a newly allocated receiver using 9529 // Replace the constructor function with a newly allocated receiver using
9532 // the index of the receiver from the top of the expression stack. 9530 // the index of the receiver from the top of the expression stack.
9533 const int receiver_index = argument_count - 1; 9531 const int receiver_index = argument_count - 1;
9534 DCHECK(environment()->ExpressionStackAt(receiver_index) == function); 9532 DCHECK(environment()->ExpressionStackAt(receiver_index) == function);
9535 environment()->SetExpressionStackAt(receiver_index, receiver); 9533 environment()->SetExpressionStackAt(receiver_index, receiver);
9536 9534
9537 if (TryInlineConstruct(expr, receiver)) { 9535 if (TryInlineConstruct(expr, receiver)) {
9538 // Inlining worked, add a dependency on the initial map to make sure that 9536 // Inlining worked, add a dependency on the initial map to make sure that
9539 // this code is deoptimized whenever the initial map of the constructor 9537 // this code is deoptimized whenever the initial map of the constructor
9540 // changes. 9538 // changes.
9541 Map::AddDependentCompilationInfo( 9539 top_info()->dependencies()->AssumeInitialMapCantChange(initial_map);
9542 initial_map, DependentCode::kInitialMapChangedGroup, top_info());
9543 return; 9540 return;
9544 } 9541 }
9545 9542
9546 // TODO(mstarzinger): For now we remove the previous HAllocate and all 9543 // TODO(mstarzinger): For now we remove the previous HAllocate and all
9547 // corresponding instructions and instead add HPushArguments for the 9544 // corresponding instructions and instead add HPushArguments for the
9548 // arguments in case inlining failed. What we actually should do is for 9545 // arguments in case inlining failed. What we actually should do is for
9549 // inlining to try to build a subgraph without mutating the parent graph. 9546 // inlining to try to build a subgraph without mutating the parent graph.
9550 HInstruction* instr = current_block()->last(); 9547 HInstruction* instr = current_block()->last();
9551 do { 9548 do {
9552 HInstruction* prev_instr = instr->previous(); 9549 HInstruction* prev_instr = instr->previous();
(...skipping 953 matching lines...) Expand 10 before | Expand all | Expand 10 after
10506 if (!left_string.is_null() && !right_string.is_null()) { 10503 if (!left_string.is_null() && !right_string.is_null()) {
10507 return AddUncasted<HStringAdd>( 10504 return AddUncasted<HStringAdd>(
10508 left, right, allocation_mode.GetPretenureMode(), 10505 left, right, allocation_mode.GetPretenureMode(),
10509 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); 10506 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
10510 } 10507 }
10511 10508
10512 // Register the dependent code with the allocation site. 10509 // Register the dependent code with the allocation site.
10513 if (!allocation_mode.feedback_site().is_null()) { 10510 if (!allocation_mode.feedback_site().is_null()) {
10514 DCHECK(!graph()->info()->IsStub()); 10511 DCHECK(!graph()->info()->IsStub());
10515 Handle<AllocationSite> site(allocation_mode.feedback_site()); 10512 Handle<AllocationSite> site(allocation_mode.feedback_site());
10516 AllocationSite::RegisterForDeoptOnTenureChange(site, top_info()); 10513 top_info()->dependencies()->AssumeTenuringDecision(site);
10517 } 10514 }
10518 10515
10519 // Inline the string addition into the stub when creating allocation 10516 // Inline the string addition into the stub when creating allocation
10520 // mementos to gather allocation site feedback, or if we can statically 10517 // mementos to gather allocation site feedback, or if we can statically
10521 // infer that we're going to create a cons string. 10518 // infer that we're going to create a cons string.
10522 if ((graph()->info()->IsStub() && 10519 if ((graph()->info()->IsStub() &&
10523 allocation_mode.CreateAllocationMementos()) || 10520 allocation_mode.CreateAllocationMementos()) ||
10524 (left->IsConstant() && 10521 (left->IsConstant() &&
10525 HConstant::cast(left)->HasStringValue() && 10522 HConstant::cast(left)->HasStringValue() &&
10526 HConstant::cast(left)->StringValue()->length() + 1 >= 10523 HConstant::cast(left)->StringValue()->length() + 1 >=
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
11077 11074
11078 HType type = instance_type == JS_ARRAY_TYPE 11075 HType type = instance_type == JS_ARRAY_TYPE
11079 ? HType::JSArray() : HType::JSObject(); 11076 ? HType::JSArray() : HType::JSObject();
11080 HValue* object_size_constant = Add<HConstant>( 11077 HValue* object_size_constant = Add<HConstant>(
11081 boilerplate_object->map()->instance_size()); 11078 boilerplate_object->map()->instance_size());
11082 11079
11083 PretenureFlag pretenure_flag = NOT_TENURED; 11080 PretenureFlag pretenure_flag = NOT_TENURED;
11084 Handle<AllocationSite> current_site(*site_context->current(), isolate()); 11081 Handle<AllocationSite> current_site(*site_context->current(), isolate());
11085 if (FLAG_allocation_site_pretenuring) { 11082 if (FLAG_allocation_site_pretenuring) {
11086 pretenure_flag = current_site->GetPretenureMode(); 11083 pretenure_flag = current_site->GetPretenureMode();
11087 AllocationSite::RegisterForDeoptOnTenureChange(current_site, top_info()); 11084 top_info()->dependencies()->AssumeTenuringDecision(current_site);
11088 } 11085 }
11089 11086
11090 AllocationSite::RegisterForDeoptOnTransitionChange(current_site, top_info()); 11087 top_info()->dependencies()->AssumeTransitionStable(current_site);
11091 11088
11092 HInstruction* object = Add<HAllocate>( 11089 HInstruction* object = Add<HAllocate>(
11093 object_size_constant, type, pretenure_flag, instance_type, current_site); 11090 object_size_constant, type, pretenure_flag, instance_type, current_site);
11094 11091
11095 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the 11092 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the
11096 // elements array may not get folded into the object. Hence, we set the 11093 // elements array may not get folded into the object. Hence, we set the
11097 // elements pointer to empty fixed array and let store elimination remove 11094 // elements pointer to empty fixed array and let store elimination remove
11098 // this store in the folding case. 11095 // this store in the folding case.
11099 HConstant* empty_fixed_array = Add<HConstant>( 11096 HConstant* empty_fixed_array = Add<HConstant>(
11100 isolate()->factory()->empty_fixed_array()); 11097 isolate()->factory()->empty_fixed_array());
(...skipping 1864 matching lines...) Expand 10 before | Expand all | Expand 10 after
12965 if (ShouldProduceTraceOutput()) { 12962 if (ShouldProduceTraceOutput()) {
12966 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12963 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12967 } 12964 }
12968 12965
12969 #ifdef DEBUG 12966 #ifdef DEBUG
12970 graph_->Verify(false); // No full verify. 12967 graph_->Verify(false); // No full verify.
12971 #endif 12968 #endif
12972 } 12969 }
12973 12970
12974 } } // namespace v8::internal 12971 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/lithium.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698