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

Side by Side Diff: src/crankshaft/hydrogen.cc

Issue 2593553002: [crankshaft] Ensure that we use inlined Array.prototype.shift only when there's no elements in the … (Closed)
Patch Set: Created 3 years, 12 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/crankshaft/hydrogen.h ('k') | src/prototype.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/crankshaft/hydrogen.h" 5 #include "src/crankshaft/hydrogen.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "src/allocation-site-scopes.h" 10 #include "src/allocation-site-scopes.h"
(...skipping 7543 matching lines...) Expand 10 before | Expand all | Expand 10 after
7554 if (TryArgumentsAccess(expr)) return; 7554 if (TryArgumentsAccess(expr)) return;
7555 7555
7556 CHECK_ALIVE(VisitForValue(expr->obj())); 7556 CHECK_ALIVE(VisitForValue(expr->obj()));
7557 if (!expr->key()->IsPropertyName() || expr->IsStringAccess()) { 7557 if (!expr->key()->IsPropertyName() || expr->IsStringAccess()) {
7558 CHECK_ALIVE(VisitForValue(expr->key())); 7558 CHECK_ALIVE(VisitForValue(expr->key()));
7559 } 7559 }
7560 7560
7561 BuildLoad(expr, expr->id()); 7561 BuildLoad(expr, expr->id());
7562 } 7562 }
7563 7563
7564 7564 HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant,
7565 HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant) { 7565 bool ensure_no_elements) {
7566 HCheckMaps* check = Add<HCheckMaps>( 7566 HCheckMaps* check = Add<HCheckMaps>(
7567 Add<HConstant>(constant), handle(constant->map())); 7567 Add<HConstant>(constant), handle(constant->map()));
7568 check->ClearDependsOnFlag(kElementsKind); 7568 check->ClearDependsOnFlag(kElementsKind);
7569 if (ensure_no_elements) {
7570 // TODO(ishell): remove this once we support NO_ELEMENTS elements kind.
7571 HValue* elements = AddLoadElements(check, nullptr);
7572 HValue* empty_elements =
7573 Add<HConstant>(isolate()->factory()->empty_fixed_array());
7574 IfBuilder if_empty(this);
7575 if_empty.IfNot<HCompareObjectEqAndBranch>(elements, empty_elements);
7576 if_empty.ThenDeopt(DeoptimizeReason::kWrongMap);
7577 if_empty.End();
7578 }
7569 return check; 7579 return check;
7570 } 7580 }
7571 7581
7572
7573 HInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype, 7582 HInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype,
7574 Handle<JSObject> holder) { 7583 Handle<JSObject> holder,
7584 bool ensure_no_elements) {
7575 PrototypeIterator iter(isolate(), prototype, kStartAtReceiver); 7585 PrototypeIterator iter(isolate(), prototype, kStartAtReceiver);
7576 while (holder.is_null() || 7586 while (holder.is_null() ||
7577 !PrototypeIterator::GetCurrent(iter).is_identical_to(holder)) { 7587 !PrototypeIterator::GetCurrent(iter).is_identical_to(holder)) {
7578 BuildConstantMapCheck(PrototypeIterator::GetCurrent<JSObject>(iter)); 7588 BuildConstantMapCheck(PrototypeIterator::GetCurrent<JSObject>(iter),
7589 ensure_no_elements);
7579 iter.Advance(); 7590 iter.Advance();
7580 if (iter.IsAtEnd()) { 7591 if (iter.IsAtEnd()) {
7581 return NULL; 7592 return NULL;
7582 } 7593 }
7583 } 7594 }
7584 return BuildConstantMapCheck(PrototypeIterator::GetCurrent<JSObject>(iter)); 7595 return BuildConstantMapCheck(holder);
7585 } 7596 }
7586 7597
7587 7598
7588 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, 7599 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder,
7589 Handle<Map> receiver_map) { 7600 Handle<Map> receiver_map) {
7590 if (!holder.is_null()) { 7601 if (!holder.is_null()) {
7591 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 7602 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
7592 BuildCheckPrototypeMaps(prototype, holder); 7603 BuildCheckPrototypeMaps(prototype, holder);
7593 } 7604 }
7594 } 7605 }
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after
8435 HInstruction* result = 8446 HInstruction* result =
8436 New<HLoadNamedField>(object, checked_object, access); 8447 New<HLoadNamedField>(object, checked_object, access);
8437 ast_context()->ReturnInstruction(result, ast_id); 8448 ast_context()->ReturnInstruction(result, ast_id);
8438 return true; 8449 return true;
8439 } 8450 }
8440 default: 8451 default:
8441 return false; 8452 return false;
8442 } 8453 }
8443 } 8454 }
8444 8455
8456 // static
8457 bool HOptimizedGraphBuilder::NoElementsInPrototypeChain(
8458 Handle<Map> receiver_map) {
8459 // TODO(ishell): remove this once we support NO_ELEMENTS elements kind.
8460 PrototypeIterator iter(receiver_map);
8461 Handle<Object> empty_fixed_array =
8462 iter.isolate()->factory()->empty_fixed_array();
8463 while (true) {
8464 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter);
8465 if (current->elements() != *empty_fixed_array) return false;
8466 iter.Advance();
8467 if (iter.IsAtEnd()) {
8468 return true;
8469 }
8470 }
8471 }
8472
8445 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( 8473 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
8446 Handle<JSFunction> function, Handle<Map> receiver_map, BailoutId ast_id, 8474 Handle<JSFunction> function, Handle<Map> receiver_map, BailoutId ast_id,
8447 int args_count_no_receiver) { 8475 int args_count_no_receiver) {
8448 if (!function->shared()->HasBuiltinFunctionId()) return false; 8476 if (!function->shared()->HasBuiltinFunctionId()) return false;
8449 BuiltinFunctionId id = function->shared()->builtin_function_id(); 8477 BuiltinFunctionId id = function->shared()->builtin_function_id();
8450 int argument_count = args_count_no_receiver + 1; // Plus receiver. 8478 int argument_count = args_count_no_receiver + 1; // Plus receiver.
8451 8479
8452 if (receiver_map.is_null()) { 8480 if (receiver_map.is_null()) {
8453 HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver); 8481 HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver);
8454 if (receiver->IsConstant() && 8482 if (receiver->IsConstant() &&
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
8689 if (!ast_context()->IsEffect()) Push(new_size); 8717 if (!ast_context()->IsEffect()) Push(new_size);
8690 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 8718 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
8691 if (!ast_context()->IsEffect()) Drop(1); 8719 if (!ast_context()->IsEffect()) Drop(1);
8692 } 8720 }
8693 8721
8694 ast_context()->ReturnValue(new_size); 8722 ast_context()->ReturnValue(new_size);
8695 return true; 8723 return true;
8696 } 8724 }
8697 case kArrayShift: { 8725 case kArrayShift: {
8698 if (!CanInlineArrayResizeOperation(receiver_map)) return false; 8726 if (!CanInlineArrayResizeOperation(receiver_map)) return false;
8727 if (!NoElementsInPrototypeChain(receiver_map)) return false;
8699 ElementsKind kind = receiver_map->elements_kind(); 8728 ElementsKind kind = receiver_map->elements_kind();
8700 8729
8701 // If there may be elements accessors in the prototype chain, the fast 8730 // If there may be elements accessors in the prototype chain, the fast
8702 // inlined version can't be used. 8731 // inlined version can't be used.
8703 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; 8732 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false;
8704 8733
8705 // If there currently can be no elements accessors on the prototype chain, 8734 // If there currently can be no elements accessors on the prototype chain,
8706 // it doesn't mean that there won't be any later. Install a full prototype 8735 // it doesn't mean that there won't be any later. Install a full prototype
8707 // chain check to trap element accessors being installed on the prototype 8736 // chain check to trap element accessors being installed on the prototype
8708 // chain, which would cause elements to go to dictionary mode and result 8737 // chain, which would cause elements to go to dictionary mode and result
8709 // in a map change. 8738 // in a map change.
8710 BuildCheckPrototypeMaps( 8739 BuildCheckPrototypeMaps(
8711 handle(JSObject::cast(receiver_map->prototype()), isolate()), 8740 handle(JSObject::cast(receiver_map->prototype()), isolate()),
8712 Handle<JSObject>::null()); 8741 Handle<JSObject>::null(), true);
8713 8742
8714 // Threshold for fast inlined Array.shift(). 8743 // Threshold for fast inlined Array.shift().
8715 HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16)); 8744 HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16));
8716 8745
8717 Drop(args_count_no_receiver); 8746 Drop(args_count_no_receiver);
8718 HValue* result; 8747 HValue* result;
8719 HValue* receiver = Pop(); 8748 HValue* receiver = Pop();
8720 HValue* checked_object = AddCheckMap(receiver, receiver_map); 8749 HValue* checked_object = AddCheckMap(receiver, receiver_map);
8721 HValue* length = Add<HLoadNamedField>( 8750 HValue* length = Add<HLoadNamedField>(
8722 receiver, checked_object, HObjectAccess::ForArrayLength(kind)); 8751 receiver, checked_object, HObjectAccess::ForArrayLength(kind));
(...skipping 4256 matching lines...) Expand 10 before | Expand all | Expand 10 after
12979 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13008 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12980 } 13009 }
12981 13010
12982 #ifdef DEBUG 13011 #ifdef DEBUG
12983 graph_->Verify(false); // No full verify. 13012 graph_->Verify(false); // No full verify.
12984 #endif 13013 #endif
12985 } 13014 }
12986 13015
12987 } // namespace internal 13016 } // namespace internal
12988 } // namespace v8 13017 } // namespace v8
OLDNEW
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | src/prototype.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698