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

Side by Side Diff: src/hydrogen.cc

Issue 7027029: Revert r8140. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 6 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 | Annotate | Revision Log
« 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 loop_information_(NULL), 61 loop_information_(NULL),
62 predecessors_(2), 62 predecessors_(2),
63 dominator_(NULL), 63 dominator_(NULL),
64 dominated_blocks_(4), 64 dominated_blocks_(4),
65 last_environment_(NULL), 65 last_environment_(NULL),
66 argument_count_(-1), 66 argument_count_(-1),
67 first_instruction_index_(-1), 67 first_instruction_index_(-1),
68 last_instruction_index_(-1), 68 last_instruction_index_(-1),
69 deleted_phis_(4), 69 deleted_phis_(4),
70 parent_loop_header_(NULL), 70 parent_loop_header_(NULL),
71 is_inline_return_target_(false) { } 71 is_inline_return_target_(false) {
72 }
72 73
73 74
74 void HBasicBlock::AttachLoopInformation() { 75 void HBasicBlock::AttachLoopInformation() {
75 ASSERT(!IsLoopHeader()); 76 ASSERT(!IsLoopHeader());
76 loop_information_ = new(zone()) HLoopInformation(this); 77 loop_information_ = new(zone()) HLoopInformation(this);
77 } 78 }
78 79
79 80
80 void HBasicBlock::DetachLoopInformation() { 81 void HBasicBlock::DetachLoopInformation() {
81 ASSERT(IsLoopHeader()); 82 ASSERT(IsLoopHeader());
(...skipping 4216 matching lines...) Expand 10 before | Expand all | Expand 10 after
4298 4299
4299 empty_true->Goto(inlined_test_context()->if_true(), false); 4300 empty_true->Goto(inlined_test_context()->if_true(), false);
4300 empty_false->Goto(inlined_test_context()->if_false(), false); 4301 empty_false->Goto(inlined_test_context()->if_false(), false);
4301 } 4302 }
4302 } 4303 }
4303 4304
4304 // Fix up the function exits. 4305 // Fix up the function exits.
4305 if (inlined_test_context() != NULL) { 4306 if (inlined_test_context() != NULL) {
4306 HBasicBlock* if_true = inlined_test_context()->if_true(); 4307 HBasicBlock* if_true = inlined_test_context()->if_true();
4307 HBasicBlock* if_false = inlined_test_context()->if_false(); 4308 HBasicBlock* if_false = inlined_test_context()->if_false();
4308 4309 if_true->SetJoinId(expr->id());
4310 if_false->SetJoinId(expr->id());
4311 ASSERT(ast_context() == inlined_test_context());
4309 // Pop the return test context from the expression context stack. 4312 // Pop the return test context from the expression context stack.
4310 ASSERT(ast_context() == inlined_test_context());
4311 ClearInlinedTestContext(); 4313 ClearInlinedTestContext();
4312 4314
4313 // Forward to the real test context. 4315 // Forward to the real test context.
4314 if (if_true->HasPredecessor()) { 4316 HBasicBlock* true_target = TestContext::cast(ast_context())->if_true();
4315 if_true->SetJoinId(expr->id()); 4317 HBasicBlock* false_target = TestContext::cast(ast_context())->if_false();
4316 HBasicBlock* true_target = TestContext::cast(ast_context())->if_true(); 4318 if_true->Goto(true_target, false);
4317 if_true->Goto(true_target, false); 4319 if_false->Goto(false_target, false);
4318 } 4320
4319 if (if_false->HasPredecessor()) { 4321 // TODO(kmillikin): Come up with a better way to handle this. It is too
4320 if_false->SetJoinId(expr->id()); 4322 // subtle. NULL here indicates that the enclosing context has no control
4321 HBasicBlock* false_target = TestContext::cast(ast_context())->if_false(); 4323 // flow to handle.
4322 if_false->Goto(false_target, false);
4323 }
4324 set_current_block(NULL); 4324 set_current_block(NULL);
4325 4325
4326 } else if (function_return()->HasPredecessor()) { 4326 } else if (function_return()->HasPredecessor()) {
4327 function_return()->SetJoinId(expr->id()); 4327 function_return()->SetJoinId(expr->id());
4328 set_current_block(function_return()); 4328 set_current_block(function_return());
4329 } else { 4329 } else {
4330 set_current_block(NULL); 4330 set_current_block(NULL);
4331 } 4331 }
4332 4332
4333 return true; 4333 return true;
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
4780 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstant1()); 4780 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstant1());
4781 ast_context()->ReturnInstruction(instr, expr->id()); 4781 ast_context()->ReturnInstruction(instr, expr->id());
4782 } 4782 }
4783 4783
4784 4784
4785 void HGraphBuilder::VisitSub(UnaryOperation* expr) { 4785 void HGraphBuilder::VisitSub(UnaryOperation* expr) {
4786 CHECK_ALIVE(VisitForValue(expr->expression())); 4786 CHECK_ALIVE(VisitForValue(expr->expression()));
4787 HValue* value = Pop(); 4787 HValue* value = Pop();
4788 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstantMinus1()); 4788 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstantMinus1());
4789 TypeInfo info = oracle()->UnaryType(expr); 4789 TypeInfo info = oracle()->UnaryType(expr);
4790 if (info.IsUninitialized()) {
4791 AddInstruction(new(zone()) HSoftDeoptimize);
4792 info = TypeInfo::Unknown();
4793 }
4794 Representation rep = ToRepresentation(info); 4790 Representation rep = ToRepresentation(info);
4795 TraceRepresentation(expr->op(), info, instr, rep); 4791 TraceRepresentation(expr->op(), info, instr, rep);
4796 instr->AssumeRepresentation(rep); 4792 instr->AssumeRepresentation(rep);
4797 ast_context()->ReturnInstruction(instr, expr->id()); 4793 ast_context()->ReturnInstruction(instr, expr->id());
4798 } 4794 }
4799 4795
4800 4796
4801 void HGraphBuilder::VisitBitNot(UnaryOperation* expr) { 4797 void HGraphBuilder::VisitBitNot(UnaryOperation* expr) {
4802 CHECK_ALIVE(VisitForValue(expr->expression())); 4798 CHECK_ALIVE(VisitForValue(expr->expression()));
4803 HValue* value = Pop(); 4799 HValue* value = Pop();
4804 TypeInfo info = oracle()->UnaryType(expr);
4805 if (info.IsUninitialized()) {
4806 AddInstruction(new(zone()) HSoftDeoptimize);
4807 }
4808 HInstruction* instr = new(zone()) HBitNot(value); 4800 HInstruction* instr = new(zone()) HBitNot(value);
4809 ast_context()->ReturnInstruction(instr, expr->id()); 4801 ast_context()->ReturnInstruction(instr, expr->id());
4810 } 4802 }
4811 4803
4812 4804
4813 void HGraphBuilder::VisitNot(UnaryOperation* expr) { 4805 void HGraphBuilder::VisitNot(UnaryOperation* expr) {
4814 // TODO(svenpanne) Perhaps a switch/virtual function is nicer here. 4806 // TODO(svenpanne) Perhaps a switch/virtual function is nicer here.
4815 if (ast_context()->IsTest()) { 4807 if (ast_context()->IsTest()) {
4816 TestContext* context = TestContext::cast(ast_context()); 4808 TestContext* context = TestContext::cast(ast_context());
4817 VisitForControl(expr->expression(), 4809 VisitForControl(expr->expression(),
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
5029 AddInstruction(length); 5021 AddInstruction(length);
5030 AddInstruction(new(zone()) HBoundsCheck(index, length)); 5022 AddInstruction(new(zone()) HBoundsCheck(index, length));
5031 return new(zone()) HStringCharCodeAt(string, index); 5023 return new(zone()) HStringCharCodeAt(string, index);
5032 } 5024 }
5033 5025
5034 5026
5035 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, 5027 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr,
5036 HValue* left, 5028 HValue* left,
5037 HValue* right) { 5029 HValue* right) {
5038 TypeInfo info = oracle()->BinaryType(expr); 5030 TypeInfo info = oracle()->BinaryType(expr);
5039 if (info.IsUninitialized()) { 5031 HInstruction* instr = BuildBinaryOperation(expr->op(), left, right, info);
5040 AddInstruction(new(zone()) HSoftDeoptimize);
5041 info = TypeInfo::Unknown();
5042 }
5043 HInstruction* instr = NULL;
5044 switch (expr->op()) {
5045 case Token::ADD:
5046 if (info.IsString()) {
5047 AddInstruction(new(zone()) HCheckNonSmi(left));
5048 AddInstruction(HCheckInstanceType::NewIsString(left));
5049 AddInstruction(new(zone()) HCheckNonSmi(right));
5050 AddInstruction(HCheckInstanceType::NewIsString(right));
5051 instr = new(zone()) HStringAdd(left, right);
5052 } else {
5053 instr = new(zone()) HAdd(left, right);
5054 }
5055 break;
5056 case Token::SUB:
5057 instr = new(zone()) HSub(left, right);
5058 break;
5059 case Token::MUL:
5060 instr = new(zone()) HMul(left, right);
5061 break;
5062 case Token::MOD:
5063 instr = new(zone()) HMod(left, right);
5064 break;
5065 case Token::DIV:
5066 instr = new(zone()) HDiv(left, right);
5067 break;
5068 case Token::BIT_XOR:
5069 instr = new(zone()) HBitXor(left, right);
5070 break;
5071 case Token::BIT_AND:
5072 instr = new(zone()) HBitAnd(left, right);
5073 break;
5074 case Token::BIT_OR:
5075 instr = new(zone()) HBitOr(left, right);
5076 break;
5077 case Token::SAR:
5078 instr = new(zone()) HSar(left, right);
5079 break;
5080 case Token::SHR:
5081 instr = new(zone()) HShr(left, right);
5082 break;
5083 case Token::SHL:
5084 instr = new(zone()) HShl(left, right);
5085 break;
5086 default:
5087 UNREACHABLE();
5088 }
5089
5090 // If we hit an uninitialized binary op stub we will get type info 5032 // If we hit an uninitialized binary op stub we will get type info
5091 // for a smi operation. If one of the operands is a constant string 5033 // for a smi operation. If one of the operands is a constant string
5092 // do not generate code assuming it is a smi operation. 5034 // do not generate code assuming it is a smi operation.
5093 if (info.IsSmi() && 5035 if (info.IsSmi() &&
5094 ((left->IsConstant() && HConstant::cast(left)->HasStringValue()) || 5036 ((left->IsConstant() && HConstant::cast(left)->HasStringValue()) ||
5095 (right->IsConstant() && HConstant::cast(right)->HasStringValue()))) { 5037 (right->IsConstant() && HConstant::cast(right)->HasStringValue()))) {
5096 return instr; 5038 return instr;
5097 } 5039 }
5098 Representation rep = ToRepresentation(info); 5040 Representation rep = ToRepresentation(info);
5099 // We only generate either int32 or generic tagged bitwise operations. 5041 // We only generate either int32 or generic tagged bitwise operations.
5100 if (instr->IsBitwiseBinaryOperation() && rep.IsDouble()) { 5042 if (instr->IsBitwiseBinaryOperation() && rep.IsDouble()) {
5101 rep = Representation::Integer32(); 5043 rep = Representation::Integer32();
5102 } 5044 }
5103 TraceRepresentation(expr->op(), info, instr, rep); 5045 TraceRepresentation(expr->op(), info, instr, rep);
5104 instr->AssumeRepresentation(rep); 5046 instr->AssumeRepresentation(rep);
5105 return instr; 5047 return instr;
5106 } 5048 }
5107 5049
5108 5050
5051 HInstruction* HGraphBuilder::BuildBinaryOperation(
5052 Token::Value op, HValue* left, HValue* right, TypeInfo info) {
5053 switch (op) {
5054 case Token::ADD:
5055 if (info.IsString()) {
5056 AddInstruction(new(zone()) HCheckNonSmi(left));
5057 AddInstruction(HCheckInstanceType::NewIsString(left));
5058 AddInstruction(new(zone()) HCheckNonSmi(right));
5059 AddInstruction(HCheckInstanceType::NewIsString(right));
5060 return new(zone()) HStringAdd(left, right);
5061 } else {
5062 return new(zone()) HAdd(left, right);
5063 }
5064 case Token::SUB: return new(zone()) HSub(left, right);
5065 case Token::MUL: return new(zone()) HMul(left, right);
5066 case Token::MOD: return new(zone()) HMod(left, right);
5067 case Token::DIV: return new(zone()) HDiv(left, right);
5068 case Token::BIT_XOR: return new(zone()) HBitXor(left, right);
5069 case Token::BIT_AND: return new(zone()) HBitAnd(left, right);
5070 case Token::BIT_OR: return new(zone()) HBitOr(left, right);
5071 case Token::SAR: return new(zone()) HSar(left, right);
5072 case Token::SHR: return new(zone()) HShr(left, right);
5073 case Token::SHL: return new(zone()) HShl(left, right);
5074 default:
5075 UNREACHABLE();
5076 return NULL;
5077 }
5078 }
5079
5080
5109 // Check for the form (%_ClassOf(foo) === 'BarClass'). 5081 // Check for the form (%_ClassOf(foo) === 'BarClass').
5110 static bool IsClassOfTest(CompareOperation* expr) { 5082 static bool IsClassOfTest(CompareOperation* expr) {
5111 if (expr->op() != Token::EQ_STRICT) return false; 5083 if (expr->op() != Token::EQ_STRICT) return false;
5112 CallRuntime* call = expr->left()->AsCallRuntime(); 5084 CallRuntime* call = expr->left()->AsCallRuntime();
5113 if (call == NULL) return false; 5085 if (call == NULL) return false;
5114 Literal* literal = expr->right()->AsLiteral(); 5086 Literal* literal = expr->right()->AsLiteral();
5115 if (literal == NULL) return false; 5087 if (literal == NULL) return false;
5116 if (!literal->handle()->IsString()) return false; 5088 if (!literal->handle()->IsString()) return false;
5117 if (!call->name()->IsEqualTo(CStrVector("_ClassOf"))) return false; 5089 if (!call->name()->IsEqualTo(CStrVector("_ClassOf"))) return false;
5118 ASSERT(call->arguments()->length() == 1); 5090 ASSERT(call->arguments()->length() == 1);
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
5296 right_literal != NULL && right_literal->handle()->IsString()) { 5268 right_literal != NULL && right_literal->handle()->IsString()) {
5297 CHECK_ALIVE(VisitForTypeOf(left_unary->expression())); 5269 CHECK_ALIVE(VisitForTypeOf(left_unary->expression()));
5298 HValue* left = Pop(); 5270 HValue* left = Pop();
5299 HInstruction* instr = new(zone()) HTypeofIs(left, 5271 HInstruction* instr = new(zone()) HTypeofIs(left,
5300 Handle<String>::cast(right_literal->handle())); 5272 Handle<String>::cast(right_literal->handle()));
5301 instr->set_position(expr->position()); 5273 instr->set_position(expr->position());
5302 ast_context()->ReturnInstruction(instr, expr->id()); 5274 ast_context()->ReturnInstruction(instr, expr->id());
5303 return; 5275 return;
5304 } 5276 }
5305 5277
5306 TypeInfo type_info = oracle()->CompareType(expr);
5307 // Check if this expression was ever executed according to type feedback.
5308 if (type_info.IsUninitialized()) {
5309 AddInstruction(new(zone()) HSoftDeoptimize);
5310 type_info = TypeInfo::Unknown();
5311 }
5312
5313 CHECK_ALIVE(VisitForValue(expr->left())); 5278 CHECK_ALIVE(VisitForValue(expr->left()));
5314 CHECK_ALIVE(VisitForValue(expr->right())); 5279 CHECK_ALIVE(VisitForValue(expr->right()));
5315 5280
5316 HValue* right = Pop(); 5281 HValue* right = Pop();
5317 HValue* left = Pop(); 5282 HValue* left = Pop();
5318 Token::Value op = expr->op(); 5283 Token::Value op = expr->op();
5319 5284
5285 TypeInfo type_info = oracle()->CompareType(expr);
5320 HInstruction* instr = NULL; 5286 HInstruction* instr = NULL;
5321 if (op == Token::INSTANCEOF) { 5287 if (op == Token::INSTANCEOF) {
5322 // Check to see if the rhs of the instanceof is a global function not 5288 // Check to see if the rhs of the instanceof is a global function not
5323 // residing in new space. If it is we assume that the function will stay the 5289 // residing in new space. If it is we assume that the function will stay the
5324 // same. 5290 // same.
5325 Handle<JSFunction> target = Handle<JSFunction>::null(); 5291 Handle<JSFunction> target = Handle<JSFunction>::null();
5326 Variable* var = expr->right()->AsVariableProxy()->AsVariable(); 5292 Variable* var = expr->right()->AsVariableProxy()->AsVariable();
5327 bool global_function = (var != NULL) && var->is_global() && !var->is_this(); 5293 bool global_function = (var != NULL) && var->is_global() && !var->is_this();
5328 if (global_function && 5294 if (global_function &&
5329 info()->has_global_object() && 5295 info()->has_global_object() &&
(...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after
6349 } 6315 }
6350 } 6316 }
6351 6317
6352 #ifdef DEBUG 6318 #ifdef DEBUG
6353 if (graph_ != NULL) graph_->Verify(); 6319 if (graph_ != NULL) graph_->Verify();
6354 if (allocator_ != NULL) allocator_->Verify(); 6320 if (allocator_ != NULL) allocator_->Verify();
6355 #endif 6321 #endif
6356 } 6322 }
6357 6323
6358 } } // namespace v8::internal 6324 } } // namespace v8::internal
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