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

Side by Side Diff: src/hydrogen.cc

Issue 1216463003: [strong] Implement strong mode semantics for the count operation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix nit Created 5 years, 5 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
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 10282 matching lines...) Expand 10 before | Expand all | Expand 10 after
10293 10293
10294 HInstruction* HOptimizedGraphBuilder::BuildIncrement( 10294 HInstruction* HOptimizedGraphBuilder::BuildIncrement(
10295 bool returns_original_input, 10295 bool returns_original_input,
10296 CountOperation* expr) { 10296 CountOperation* expr) {
10297 // The input to the count operation is on top of the expression stack. 10297 // The input to the count operation is on top of the expression stack.
10298 Representation rep = RepresentationFor(expr->type()); 10298 Representation rep = RepresentationFor(expr->type());
10299 if (rep.IsNone() || rep.IsTagged()) { 10299 if (rep.IsNone() || rep.IsTagged()) {
10300 rep = Representation::Smi(); 10300 rep = Representation::Smi();
10301 } 10301 }
10302 10302
10303 if (returns_original_input) { 10303 if (returns_original_input && !is_strong(function_language_mode())) {
10304 // We need an explicit HValue representing ToNumber(input). The 10304 // We need an explicit HValue representing ToNumber(input). The
10305 // actual HChange instruction we need is (sometimes) added in a later 10305 // actual HChange instruction we need is (sometimes) added in a later
10306 // phase, so it is not available now to be used as an input to HAdd and 10306 // phase, so it is not available now to be used as an input to HAdd and
10307 // as the return value. 10307 // as the return value.
10308 HInstruction* number_input = AddUncasted<HForceRepresentation>(Pop(), rep); 10308 HInstruction* number_input = AddUncasted<HForceRepresentation>(Pop(), rep);
10309 if (!rep.IsDouble()) { 10309 if (!rep.IsDouble()) {
10310 number_input->SetFlag(HInstruction::kFlexibleRepresentation); 10310 number_input->SetFlag(HInstruction::kFlexibleRepresentation);
10311 number_input->SetFlag(HInstruction::kCannotBeTagged); 10311 number_input->SetFlag(HInstruction::kCannotBeTagged);
10312 } 10312 }
10313 Push(number_input); 10313 Push(number_input);
10314 } 10314 }
10315 10315
10316 // The addition has no side effects, so we do not need 10316 // The addition has no side effects, so we do not need
10317 // to simulate the expression stack after this instruction. 10317 // to simulate the expression stack after this instruction.
10318 // Any later failures deopt to the load of the input or earlier. 10318 // Any later failures deopt to the load of the input or earlier.
10319 HConstant* delta = (expr->op() == Token::INC) 10319 HConstant* delta = (expr->op() == Token::INC)
10320 ? graph()->GetConstant1() 10320 ? graph()->GetConstant1()
10321 : graph()->GetConstantMinus1(); 10321 : graph()->GetConstantMinus1();
10322 HInstruction* instr = 10322 HInstruction* instr =
10323 AddUncasted<HAdd>(Top(), delta, strength(function_language_mode())); 10323 AddUncasted<HAdd>(Top(), delta, strength(function_language_mode()));
10324 if (instr->IsAdd()) { 10324 if (instr->IsAdd()) {
10325 HAdd* add = HAdd::cast(instr); 10325 HAdd* add = HAdd::cast(instr);
10326 add->set_observed_input_representation(1, rep); 10326 if (!is_strong(function_language_mode())) {
rossberg 2015/06/30 12:53:52 Hm, why no recording in strong mode? Can you add a
conradw 2015/06/30 14:01:10 Urk, this was something I added while misunderstan
10327 add->set_observed_input_representation(1, rep);
10328 }
10327 add->set_observed_input_representation(2, Representation::Smi()); 10329 add->set_observed_input_representation(2, Representation::Smi());
10328 } 10330 }
10331 if (!is_strong(function_language_mode())) {
10332 instr->ClearAllSideEffects();
10333 } else {
10334 Add<HSimulate>(expr->ToNumberId(), REMOVABLE_SIMULATE);
10335 }
10329 instr->SetFlag(HInstruction::kCannotBeTagged); 10336 instr->SetFlag(HInstruction::kCannotBeTagged);
10330 instr->ClearAllSideEffects();
10331 return instr; 10337 return instr;
10332 } 10338 }
10333 10339
10334 10340
10335 void HOptimizedGraphBuilder::BuildStoreForEffect(Expression* expr, 10341 void HOptimizedGraphBuilder::BuildStoreForEffect(Expression* expr,
10336 Property* prop, 10342 Property* prop,
10337 BailoutId ast_id, 10343 BailoutId ast_id,
10338 BailoutId return_id, 10344 BailoutId return_id,
10339 HValue* object, 10345 HValue* object,
10340 HValue* key, 10346 HValue* key,
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
10604 Type* left_type = expr->left()->bounds().lower; 10610 Type* left_type = expr->left()->bounds().lower;
10605 Type* right_type = expr->right()->bounds().lower; 10611 Type* right_type = expr->right()->bounds().lower;
10606 Type* result_type = expr->bounds().lower; 10612 Type* result_type = expr->bounds().lower;
10607 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); 10613 Maybe<int> fixed_right_arg = expr->fixed_right_arg();
10608 Handle<AllocationSite> allocation_site = expr->allocation_site(); 10614 Handle<AllocationSite> allocation_site = expr->allocation_site();
10609 10615
10610 HAllocationMode allocation_mode; 10616 HAllocationMode allocation_mode;
10611 if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) { 10617 if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) {
10612 allocation_mode = HAllocationMode(allocation_site); 10618 allocation_mode = HAllocationMode(allocation_site);
10613 } 10619 }
10614
10615 HValue* result = HGraphBuilder::BuildBinaryOperation( 10620 HValue* result = HGraphBuilder::BuildBinaryOperation(
10616 expr->op(), left, right, left_type, right_type, result_type, 10621 expr->op(), left, right, left_type, right_type, result_type,
10617 fixed_right_arg, allocation_mode, strength(function_language_mode())); 10622 fixed_right_arg, allocation_mode, strength(function_language_mode()),
10623 expr->id());
10618 // Add a simulate after instructions with observable side effects, and 10624 // Add a simulate after instructions with observable side effects, and
10619 // after phis, which are the result of BuildBinaryOperation when we 10625 // after phis, which are the result of BuildBinaryOperation when we
10620 // inlined some complex subgraph. 10626 // inlined some complex subgraph.
10621 if (result->HasObservableSideEffects() || result->IsPhi()) { 10627 if (result->HasObservableSideEffects() || result->IsPhi()) {
10622 if (push_sim_result == PUSH_BEFORE_SIMULATE) { 10628 if (push_sim_result == PUSH_BEFORE_SIMULATE) {
10623 Push(result); 10629 Push(result);
10624 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 10630 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
10625 Drop(1); 10631 Drop(1);
10626 } else { 10632 } else {
10627 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 10633 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
10628 } 10634 }
10629 } 10635 }
10630 return result; 10636 return result;
10631 } 10637 }
10632 10638
10633 10639
10634 HValue* HGraphBuilder::BuildBinaryOperation(Token::Value op, HValue* left, 10640 HValue* HGraphBuilder::BuildBinaryOperation(
10635 HValue* right, Type* left_type, 10641 Token::Value op, HValue* left, HValue* right, Type* left_type,
10636 Type* right_type, Type* result_type, 10642 Type* right_type, Type* result_type, Maybe<int> fixed_right_arg,
10637 Maybe<int> fixed_right_arg, 10643 HAllocationMode allocation_mode, Strength strength, BailoutId opt_id) {
10638 HAllocationMode allocation_mode,
10639 Strength strength) {
10640 bool maybe_string_add = false; 10644 bool maybe_string_add = false;
10641 if (op == Token::ADD) { 10645 if (op == Token::ADD) {
10642 // If we are adding constant string with something for which we don't have 10646 // If we are adding constant string with something for which we don't have
10643 // a feedback yet, assume that it's also going to be a string and don't 10647 // a feedback yet, assume that it's also going to be a string and don't
10644 // generate deopt instructions. 10648 // generate deopt instructions.
10645 if (!left_type->IsInhabited() && right->IsConstant() && 10649 if (!left_type->IsInhabited() && right->IsConstant() &&
10646 HConstant::cast(right)->HasStringValue()) { 10650 HConstant::cast(right)->HasStringValue()) {
10647 left_type = Type::String(); 10651 left_type = Type::String();
10648 } 10652 }
10649 10653
(...skipping 22 matching lines...) Expand all
10672 10676
10673 if (!right_type->IsInhabited()) { 10677 if (!right_type->IsInhabited()) {
10674 Add<HDeoptimize>( 10678 Add<HDeoptimize>(
10675 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation, 10679 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation,
10676 Deoptimizer::SOFT); 10680 Deoptimizer::SOFT);
10677 right_type = Type::Any(zone()); 10681 right_type = Type::Any(zone());
10678 right_rep = RepresentationFor(right_type); 10682 right_rep = RepresentationFor(right_type);
10679 maybe_string_add = op == Token::ADD; 10683 maybe_string_add = op == Token::ADD;
10680 } 10684 }
10681 10685
10682 if (!maybe_string_add) { 10686 if (!maybe_string_add && !is_strong(strength)) {
10683 left = TruncateToNumber(left, &left_type); 10687 left = TruncateToNumber(left, &left_type);
10684 right = TruncateToNumber(right, &right_type); 10688 right = TruncateToNumber(right, &right_type);
10685 } 10689 }
10686 10690
10687 // Special case for string addition here. 10691 // Special case for string addition here.
10688 if (op == Token::ADD && 10692 if (op == Token::ADD &&
10689 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { 10693 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) {
10690 // Validate type feedback for left argument. 10694 // Validate type feedback for left argument.
10691 if (left_type->Is(Type::String())) { 10695 if (left_type->Is(Type::String())) {
10692 left = BuildCheckString(left); 10696 left = BuildCheckString(left);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
10782 HInstruction* instr = NULL; 10786 HInstruction* instr = NULL;
10783 // Only the stub is allowed to call into the runtime, since otherwise we would 10787 // Only the stub is allowed to call into the runtime, since otherwise we would
10784 // inline several instructions (including the two pushes) for every tagged 10788 // inline several instructions (including the two pushes) for every tagged
10785 // operation in optimized code, which is more expensive, than a stub call. 10789 // operation in optimized code, which is more expensive, than a stub call.
10786 if (graph()->info()->IsStub() && is_non_primitive) { 10790 if (graph()->info()->IsStub() && is_non_primitive) {
10787 HValue* function = 10791 HValue* function =
10788 AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op, strength)); 10792 AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op, strength));
10789 Add<HPushArguments>(left, right); 10793 Add<HPushArguments>(left, right);
10790 instr = AddUncasted<HInvokeFunction>(function, 2); 10794 instr = AddUncasted<HInvokeFunction>(function, 2);
10791 } else { 10795 } else {
10796 if (is_strong(strength) && Token::IsBitOp(op)) {
10797 IfBuilder if_builder(this);
10798 if_builder.If<HHasInstanceTypeAndBranch>(left, ODDBALL_TYPE);
10799 if_builder.OrIf<HHasInstanceTypeAndBranch>(right, ODDBALL_TYPE);
10800 if_builder.Then();
10801 Add<HCallRuntime>(
10802 isolate()->factory()->empty_string(),
10803 Runtime::FunctionForId(Runtime::kThrowStrongModeImplicitConversion),
10804 0);
10805 if (!graph()->info()->IsStub()) {
10806 Add<HSimulate>(opt_id, REMOVABLE_SIMULATE);
10807 }
10808 if_builder.End();
10809 }
10792 switch (op) { 10810 switch (op) {
10793 case Token::ADD: 10811 case Token::ADD:
10794 instr = AddUncasted<HAdd>(left, right, strength); 10812 instr = AddUncasted<HAdd>(left, right, strength);
10795 break; 10813 break;
10796 case Token::SUB: 10814 case Token::SUB:
10797 instr = AddUncasted<HSub>(left, right, strength); 10815 instr = AddUncasted<HSub>(left, right, strength);
10798 break; 10816 break;
10799 case Token::MUL: 10817 case Token::MUL:
10800 instr = AddUncasted<HMul>(left, right, strength); 10818 instr = AddUncasted<HMul>(left, right, strength);
10801 break; 10819 break;
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
11239 AddSimulate(bailout_id, REMOVABLE_SIMULATE); 11257 AddSimulate(bailout_id, REMOVABLE_SIMULATE);
11240 Drop(1); 11258 Drop(1);
11241 } else { 11259 } else {
11242 AddSimulate(bailout_id, REMOVABLE_SIMULATE); 11260 AddSimulate(bailout_id, REMOVABLE_SIMULATE);
11243 } 11261 }
11244 } 11262 }
11245 // TODO(jkummerow): Can we make this more efficient? 11263 // TODO(jkummerow): Can we make this more efficient?
11246 HBranch* branch = New<HBranch>(result); 11264 HBranch* branch = New<HBranch>(result);
11247 return branch; 11265 return branch;
11248 } else { 11266 } else {
11267 if (is_strong(function_language_mode()) &&
11268 Token::IsOrderedRelationalCompareOp(op)) {
11269 IfBuilder if_builder(this);
11270 if_builder.If<HHasInstanceTypeAndBranch>(left, ODDBALL_TYPE);
11271 if_builder.OrIf<HHasInstanceTypeAndBranch>(right, ODDBALL_TYPE);
11272 if_builder.Then();
11273 Add<HCallRuntime>(
11274 isolate()->factory()->empty_string(),
11275 Runtime::FunctionForId(Runtime::kThrowStrongModeImplicitConversion),
11276 0);
11277 Add<HSimulate>(bailout_id, REMOVABLE_SIMULATE);
11278 if_builder.End();
11279 }
11249 HCompareNumericAndBranch* result = 11280 HCompareNumericAndBranch* result =
11250 New<HCompareNumericAndBranch>(left, right, op); 11281 New<HCompareNumericAndBranch>(left, right, op);
11251 result->set_observed_input_representation(left_rep, right_rep); 11282 result->set_observed_input_representation(left_rep, right_rep);
11252 if (top_info()->is_tracking_positions()) { 11283 if (top_info()->is_tracking_positions()) {
11253 result->SetOperandPositions(zone(), left_position, right_position); 11284 result->SetOperandPositions(zone(), left_position, right_position);
11254 } 11285 }
11255 return result; 11286 return result;
11256 } 11287 }
11257 } 11288 }
11258 } 11289 }
(...skipping 1945 matching lines...) Expand 10 before | Expand all | Expand 10 after
13204 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13235 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13205 } 13236 }
13206 13237
13207 #ifdef DEBUG 13238 #ifdef DEBUG
13208 graph_->Verify(false); // No full verify. 13239 graph_->Verify(false); // No full verify.
13209 #endif 13240 #endif
13210 } 13241 }
13211 13242
13212 } // namespace internal 13243 } // namespace internal
13213 } // namespace v8 13244 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698