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

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: cl feedback + eliminate runtime check 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
« 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 <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 add->set_observed_input_representation(1, rep);
10327 add->set_observed_input_representation(2, Representation::Smi()); 10327 add->set_observed_input_representation(2, Representation::Smi());
10328 } 10328 }
10329 if (!is_strong(function_language_mode())) {
10330 instr->ClearAllSideEffects();
10331 } else {
10332 Add<HSimulate>(expr->ToNumberId(), REMOVABLE_SIMULATE);
10333 }
10329 instr->SetFlag(HInstruction::kCannotBeTagged); 10334 instr->SetFlag(HInstruction::kCannotBeTagged);
10330 instr->ClearAllSideEffects();
10331 return instr; 10335 return instr;
10332 } 10336 }
10333 10337
10334 10338
10335 void HOptimizedGraphBuilder::BuildStoreForEffect(Expression* expr, 10339 void HOptimizedGraphBuilder::BuildStoreForEffect(Expression* expr,
10336 Property* prop, 10340 Property* prop,
10337 BailoutId ast_id, 10341 BailoutId ast_id,
10338 BailoutId return_id, 10342 BailoutId return_id,
10339 HValue* object, 10343 HValue* object,
10340 HValue* key, 10344 HValue* key,
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
10604 Type* left_type = expr->left()->bounds().lower; 10608 Type* left_type = expr->left()->bounds().lower;
10605 Type* right_type = expr->right()->bounds().lower; 10609 Type* right_type = expr->right()->bounds().lower;
10606 Type* result_type = expr->bounds().lower; 10610 Type* result_type = expr->bounds().lower;
10607 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); 10611 Maybe<int> fixed_right_arg = expr->fixed_right_arg();
10608 Handle<AllocationSite> allocation_site = expr->allocation_site(); 10612 Handle<AllocationSite> allocation_site = expr->allocation_site();
10609 10613
10610 HAllocationMode allocation_mode; 10614 HAllocationMode allocation_mode;
10611 if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) { 10615 if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) {
10612 allocation_mode = HAllocationMode(allocation_site); 10616 allocation_mode = HAllocationMode(allocation_site);
10613 } 10617 }
10614
10615 HValue* result = HGraphBuilder::BuildBinaryOperation( 10618 HValue* result = HGraphBuilder::BuildBinaryOperation(
10616 expr->op(), left, right, left_type, right_type, result_type, 10619 expr->op(), left, right, left_type, right_type, result_type,
10617 fixed_right_arg, allocation_mode, strength(function_language_mode())); 10620 fixed_right_arg, allocation_mode, strength(function_language_mode()),
10621 expr->id());
10618 // Add a simulate after instructions with observable side effects, and 10622 // Add a simulate after instructions with observable side effects, and
10619 // after phis, which are the result of BuildBinaryOperation when we 10623 // after phis, which are the result of BuildBinaryOperation when we
10620 // inlined some complex subgraph. 10624 // inlined some complex subgraph.
10621 if (result->HasObservableSideEffects() || result->IsPhi()) { 10625 if (result->HasObservableSideEffects() || result->IsPhi()) {
10622 if (push_sim_result == PUSH_BEFORE_SIMULATE) { 10626 if (push_sim_result == PUSH_BEFORE_SIMULATE) {
10623 Push(result); 10627 Push(result);
10624 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 10628 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
10625 Drop(1); 10629 Drop(1);
10626 } else { 10630 } else {
10627 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 10631 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
10628 } 10632 }
10629 } 10633 }
10630 return result; 10634 return result;
10631 } 10635 }
10632 10636
10633 10637
10634 HValue* HGraphBuilder::BuildBinaryOperation(Token::Value op, HValue* left, 10638 HValue* HGraphBuilder::BuildBinaryOperation(
10635 HValue* right, Type* left_type, 10639 Token::Value op, HValue* left, HValue* right, Type* left_type,
10636 Type* right_type, Type* result_type, 10640 Type* right_type, Type* result_type, Maybe<int> fixed_right_arg,
10637 Maybe<int> fixed_right_arg, 10641 HAllocationMode allocation_mode, Strength strength, BailoutId opt_id) {
10638 HAllocationMode allocation_mode,
10639 Strength strength) {
10640 bool maybe_string_add = false; 10642 bool maybe_string_add = false;
10641 if (op == Token::ADD) { 10643 if (op == Token::ADD) {
10642 // If we are adding constant string with something for which we don't have 10644 // 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 10645 // a feedback yet, assume that it's also going to be a string and don't
10644 // generate deopt instructions. 10646 // generate deopt instructions.
10645 if (!left_type->IsInhabited() && right->IsConstant() && 10647 if (!left_type->IsInhabited() && right->IsConstant() &&
10646 HConstant::cast(right)->HasStringValue()) { 10648 HConstant::cast(right)->HasStringValue()) {
10647 left_type = Type::String(); 10649 left_type = Type::String();
10648 } 10650 }
10649 10651
(...skipping 22 matching lines...) Expand all
10672 10674
10673 if (!right_type->IsInhabited()) { 10675 if (!right_type->IsInhabited()) {
10674 Add<HDeoptimize>( 10676 Add<HDeoptimize>(
10675 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation, 10677 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation,
10676 Deoptimizer::SOFT); 10678 Deoptimizer::SOFT);
10677 right_type = Type::Any(zone()); 10679 right_type = Type::Any(zone());
10678 right_rep = RepresentationFor(right_type); 10680 right_rep = RepresentationFor(right_type);
10679 maybe_string_add = op == Token::ADD; 10681 maybe_string_add = op == Token::ADD;
10680 } 10682 }
10681 10683
10682 if (!maybe_string_add) { 10684 if (!maybe_string_add && !is_strong(strength)) {
10683 left = TruncateToNumber(left, &left_type); 10685 left = TruncateToNumber(left, &left_type);
10684 right = TruncateToNumber(right, &right_type); 10686 right = TruncateToNumber(right, &right_type);
10685 } 10687 }
10686 10688
10687 // Special case for string addition here. 10689 // Special case for string addition here.
10688 if (op == Token::ADD && 10690 if (op == Token::ADD &&
10689 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { 10691 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) {
10690 // Validate type feedback for left argument. 10692 // Validate type feedback for left argument.
10691 if (left_type->Is(Type::String())) { 10693 if (left_type->Is(Type::String())) {
10692 left = BuildCheckString(left); 10694 left = BuildCheckString(left);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
10782 HInstruction* instr = NULL; 10784 HInstruction* instr = NULL;
10783 // Only the stub is allowed to call into the runtime, since otherwise we would 10785 // 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 10786 // inline several instructions (including the two pushes) for every tagged
10785 // operation in optimized code, which is more expensive, than a stub call. 10787 // operation in optimized code, which is more expensive, than a stub call.
10786 if (graph()->info()->IsStub() && is_non_primitive) { 10788 if (graph()->info()->IsStub() && is_non_primitive) {
10787 HValue* function = 10789 HValue* function =
10788 AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op, strength)); 10790 AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op, strength));
10789 Add<HPushArguments>(left, right); 10791 Add<HPushArguments>(left, right);
10790 instr = AddUncasted<HInvokeFunction>(function, 2); 10792 instr = AddUncasted<HInvokeFunction>(function, 2);
10791 } else { 10793 } else {
10794 if (is_strong(strength) && Token::IsBitOp(op)) {
10795 IfBuilder if_builder(this);
10796 if_builder.If<HHasInstanceTypeAndBranch>(left, ODDBALL_TYPE);
10797 if_builder.OrIf<HHasInstanceTypeAndBranch>(right, ODDBALL_TYPE);
10798 if_builder.Then();
10799 Add<HCallRuntime>(
10800 isolate()->factory()->empty_string(),
10801 Runtime::FunctionForId(Runtime::kThrowStrongModeImplicitConversion),
10802 0);
10803 if (!graph()->info()->IsStub()) {
10804 Add<HSimulate>(opt_id, REMOVABLE_SIMULATE);
10805 }
10806 if_builder.End();
10807 }
10792 switch (op) { 10808 switch (op) {
10793 case Token::ADD: 10809 case Token::ADD:
10794 instr = AddUncasted<HAdd>(left, right, strength); 10810 instr = AddUncasted<HAdd>(left, right, strength);
10795 break; 10811 break;
10796 case Token::SUB: 10812 case Token::SUB:
10797 instr = AddUncasted<HSub>(left, right, strength); 10813 instr = AddUncasted<HSub>(left, right, strength);
10798 break; 10814 break;
10799 case Token::MUL: 10815 case Token::MUL:
10800 instr = AddUncasted<HMul>(left, right, strength); 10816 instr = AddUncasted<HMul>(left, right, strength);
10801 break; 10817 break;
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
11239 AddSimulate(bailout_id, REMOVABLE_SIMULATE); 11255 AddSimulate(bailout_id, REMOVABLE_SIMULATE);
11240 Drop(1); 11256 Drop(1);
11241 } else { 11257 } else {
11242 AddSimulate(bailout_id, REMOVABLE_SIMULATE); 11258 AddSimulate(bailout_id, REMOVABLE_SIMULATE);
11243 } 11259 }
11244 } 11260 }
11245 // TODO(jkummerow): Can we make this more efficient? 11261 // TODO(jkummerow): Can we make this more efficient?
11246 HBranch* branch = New<HBranch>(result); 11262 HBranch* branch = New<HBranch>(result);
11247 return branch; 11263 return branch;
11248 } else { 11264 } else {
11249 HCompareNumericAndBranch* result = 11265 HCompareNumericAndBranch* result = New<HCompareNumericAndBranch>(
11250 New<HCompareNumericAndBranch>(left, right, op); 11266 left, right, op, strength(function_language_mode()));
11251 result->set_observed_input_representation(left_rep, right_rep); 11267 result->set_observed_input_representation(left_rep, right_rep);
11252 if (top_info()->is_tracking_positions()) { 11268 if (top_info()->is_tracking_positions()) {
11253 result->SetOperandPositions(zone(), left_position, right_position); 11269 result->SetOperandPositions(zone(), left_position, right_position);
11254 } 11270 }
11255 return result; 11271 return result;
11256 } 11272 }
11257 } 11273 }
11258 } 11274 }
11259 11275
11260 11276
(...skipping 1943 matching lines...) Expand 10 before | Expand all | Expand 10 after
13204 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13220 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13205 } 13221 }
13206 13222
13207 #ifdef DEBUG 13223 #ifdef DEBUG
13208 graph_->Verify(false); // No full verify. 13224 graph_->Verify(false); // No full verify.
13209 #endif 13225 #endif
13210 } 13226 }
13211 13227
13212 } // namespace internal 13228 } // namespace internal
13213 } // namespace v8 13229 } // namespace v8
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