Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 #include "vm/longjump.h" | 9 #include "vm/longjump.h" |
| 10 #include "vm/os.h" | 10 #include "vm/os.h" |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 | 122 |
| 123 void TestGraphVisitor::BranchOnValue(Value* value) { | 123 void TestGraphVisitor::BranchOnValue(Value* value) { |
| 124 BranchInstr* branch = new BranchInstr(value); | 124 BranchInstr* branch = new BranchInstr(value); |
| 125 AddInstruction(branch); | 125 AddInstruction(branch); |
| 126 CloseFragment(); | 126 CloseFragment(); |
| 127 true_successor_address_ = branch->true_successor_address(); | 127 true_successor_address_ = branch->true_successor_address(); |
| 128 false_successor_address_ = branch->false_successor_address(); | 128 false_successor_address_ = branch->false_successor_address(); |
| 129 } | 129 } |
| 130 | 130 |
| 131 | 131 |
| 132 void ArgumentGraphVisitor::ReturnValue(Value* value) { | |
| 133 value_ = value; | |
| 134 if (value->IsConstant()) { | |
| 135 AddInstruction(new BindInstr(temp_index(), value)); | |
| 136 value_ = new TempVal(AllocateTempIndex()); | |
| 137 } | |
| 138 } | |
| 139 | |
| 140 | |
| 132 void EffectGraphVisitor::Bailout(const char* reason) { | 141 void EffectGraphVisitor::Bailout(const char* reason) { |
| 133 owner()->Bailout(reason); | 142 owner()->Bailout(reason); |
| 134 } | 143 } |
| 135 | 144 |
| 136 | 145 |
| 137 // 'bailout' is a statement (without a semicolon), typically a return. | 146 // 'bailout' is a statement (without a semicolon), typically a return. |
| 138 #define CHECK_ALIVE(bailout) \ | 147 #define CHECK_ALIVE(bailout) \ |
| 139 do { \ | 148 do { \ |
| 140 if (!is_open()) { \ | 149 if (!is_open()) { \ |
| 141 bailout; \ | 150 bailout; \ |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 | 224 |
| 216 // <Expression> :: BinaryOp { kind: Token::Kind | 225 // <Expression> :: BinaryOp { kind: Token::Kind |
| 217 // left: <Expression> | 226 // left: <Expression> |
| 218 // right: <Expression> } | 227 // right: <Expression> } |
| 219 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 228 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 220 // Operators "&&" and "||" cannot be overloaded therefore do not call | 229 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 221 // operator. | 230 // operator. |
| 222 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 231 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 223 Bailout("EffectGraphVisitor::VisitBinaryOpNode AND/OR"); | 232 Bailout("EffectGraphVisitor::VisitBinaryOpNode AND/OR"); |
| 224 } | 233 } |
| 225 ValueGraphVisitor for_left_value(owner(), temp_index()); | 234 ArgumentGraphVisitor for_left_value(owner(), temp_index()); |
| 226 node->left()->Visit(&for_left_value); | 235 node->left()->Visit(&for_left_value); |
| 227 Append(for_left_value); | 236 Append(for_left_value); |
| 228 CHECK_ALIVE(return); | 237 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); |
| 229 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | |
| 230 node->right()->Visit(&for_right_value); | 238 node->right()->Visit(&for_right_value); |
| 231 Append(for_right_value); | 239 Append(for_right_value); |
| 232 CHECK_ALIVE(return); | |
| 233 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 240 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 234 arguments->Add(for_left_value.value()); | 241 arguments->Add(for_left_value.value()); |
| 235 arguments->Add(for_right_value.value()); | 242 arguments->Add(for_right_value.value()); |
| 236 InstanceCallComp* call = new InstanceCallComp(node->Name(), arguments); | 243 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |
| 244 InstanceCallComp* call = | |
| 245 new InstanceCallComp(node, name, arguments, Array::ZoneHandle(), 2); | |
| 237 ReturnComputation(call); | 246 ReturnComputation(call); |
| 238 } | 247 } |
| 239 | 248 |
| 240 | 249 |
| 241 void EffectGraphVisitor::VisitStringConcatNode(StringConcatNode* node) { | 250 void EffectGraphVisitor::VisitStringConcatNode(StringConcatNode* node) { |
| 242 Bailout("EffectGraphVisitor::VisitStringConcatNode"); | 251 Bailout("EffectGraphVisitor::VisitStringConcatNode"); |
| 243 } | 252 } |
| 244 | 253 |
| 245 | 254 |
| 246 // <Expression> :: Comparison { kind: Token::Kind | 255 // <Expression> :: Comparison { kind: Token::Kind |
| 247 // left: <Expression> | 256 // left: <Expression> |
| 248 // right: <Expression> } | 257 // right: <Expression> } |
| 249 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { | 258 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
| 250 if (Token::IsInstanceofOperator(node->kind())) { | 259 if (Token::IsInstanceofOperator(node->kind())) { |
| 251 Bailout("instanceof not yet implemented"); | 260 Bailout("instanceof not yet implemented"); |
| 252 } else if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { | 261 } else if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { |
| 253 Bailout("'==' or '!=' comparison not yet implemented"); | 262 Bailout("'==' or '!=' comparison not yet implemented"); |
| 254 } | 263 } |
| 255 ValueGraphVisitor for_left_value(owner(), temp_index()); | 264 |
| 256 node->left()->Visit(&for_left_value); | |
| 257 Append(for_left_value); | |
| 258 CHECK_ALIVE(return); | |
| 259 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | |
| 260 node->right()->Visit(&for_right_value); | |
| 261 Append(for_right_value); | |
| 262 CHECK_ALIVE(return); | |
| 263 if ((node->kind() == Token::kEQ_STRICT) || | 265 if ((node->kind() == Token::kEQ_STRICT) || |
| 264 (node->kind() == Token::kNE_STRICT)) { | 266 (node->kind() == Token::kNE_STRICT)) { |
| 267 ValueGraphVisitor for_left_value(owner(), temp_index()); | |
| 268 node->left()->Visit(&for_left_value); | |
| 269 Append(for_left_value); | |
| 270 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | |
| 271 node->right()->Visit(&for_right_value); | |
| 272 Append(for_right_value); | |
|
srdjan
2012/03/01 17:16:56
Why don't you materialize the constants for strict
| |
| 265 StrictCompareComp* comp = new StrictCompareComp( | 273 StrictCompareComp* comp = new StrictCompareComp( |
| 266 node->kind(), for_left_value.value(), for_right_value.value()); | 274 node->kind(), for_left_value.value(), for_right_value.value()); |
| 267 ReturnComputation(comp); | 275 ReturnComputation(comp); |
| 268 return; | 276 return; |
| 269 } | 277 } |
| 278 | |
| 279 ArgumentGraphVisitor for_left_value(owner(), temp_index()); | |
| 280 node->left()->Visit(&for_left_value); | |
| 281 Append(for_left_value); | |
| 282 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | |
| 283 node->right()->Visit(&for_right_value); | |
| 284 Append(for_right_value); | |
| 270 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 285 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 271 arguments->Add(for_left_value.value()); | 286 arguments->Add(for_left_value.value()); |
| 272 arguments->Add(for_right_value.value()); | 287 arguments->Add(for_right_value.value()); |
| 273 InstanceCallComp* call = new InstanceCallComp(node->Name(), arguments); | 288 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |
| 289 InstanceCallComp* call = | |
| 290 new InstanceCallComp(node, name, arguments, Array::ZoneHandle(), 2); | |
| 274 ReturnComputation(call); | 291 ReturnComputation(call); |
| 275 } | 292 } |
| 276 | 293 |
| 277 | 294 |
| 278 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 295 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| 279 // "!" cannot be overloaded, therefore do not call operator. | 296 // "!" cannot be overloaded, therefore do not call operator. |
| 280 if (node->kind() == Token::kNOT) { | 297 if (node->kind() == Token::kNOT) { |
| 281 Bailout("EffectGraphVisitor::VisitUnaryOpNode NOT"); | 298 Bailout("EffectGraphVisitor::VisitUnaryOpNode NOT"); |
| 282 } | 299 } |
| 283 ValueGraphVisitor for_value(owner(), temp_index()); | 300 ArgumentGraphVisitor for_value(owner(), temp_index()); |
| 284 node->operand()->Visit(&for_value); | 301 node->operand()->Visit(&for_value); |
| 285 Append(for_value); | 302 Append(for_value); |
| 286 ZoneGrowableArray<Value*>* argument = new ZoneGrowableArray<Value*>(1); | 303 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); |
| 287 argument->Add(for_value.value()); | 304 arguments->Add(for_value.value()); |
| 288 InstanceCallComp* call = new InstanceCallComp(node->Name(), argument); | 305 const String& name = |
| 306 String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB) | |
| 307 ? Token::Str(Token::kNEGATE) | |
| 308 : node->Name())); | |
| 309 InstanceCallComp* call = | |
| 310 new InstanceCallComp(node, name, arguments, Array::ZoneHandle(), 1); | |
| 289 ReturnComputation(call); | 311 ReturnComputation(call); |
| 290 } | 312 } |
| 291 | 313 |
| 292 | 314 |
| 293 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { | 315 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { |
| 294 Bailout("EffectGraphVisitor::VisitIncrOpLocalNode"); | 316 Bailout("EffectGraphVisitor::VisitIncrOpLocalNode"); |
| 295 } | 317 } |
| 296 | 318 |
| 297 | 319 |
| 298 void EffectGraphVisitor::VisitIncrOpInstanceFieldNode( | 320 void EffectGraphVisitor::VisitIncrOpInstanceFieldNode( |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 383 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 405 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| 384 Bailout("EffectGraphVisitor::VisitArrayNode"); | 406 Bailout("EffectGraphVisitor::VisitArrayNode"); |
| 385 } | 407 } |
| 386 | 408 |
| 387 | 409 |
| 388 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { | 410 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
| 389 Bailout("EffectGraphVisitor::VisitClosureNode"); | 411 Bailout("EffectGraphVisitor::VisitClosureNode"); |
| 390 } | 412 } |
| 391 | 413 |
| 392 | 414 |
| 415 void EffectGraphVisitor::TranslateArgumentList( | |
| 416 const ArgumentListNode& node, | |
| 417 intptr_t next_temp_index, | |
| 418 ZoneGrowableArray<Value*>* values) { | |
| 419 for (intptr_t i = 0; i < node.length(); ++i) { | |
| 420 ArgumentGraphVisitor for_argument(owner(), next_temp_index); | |
| 421 node.NodeAt(i)->Visit(&for_argument); | |
| 422 Append(for_argument); | |
| 423 next_temp_index = for_argument.temp_index(); | |
| 424 values->Add(for_argument.value()); | |
| 425 } | |
| 426 } | |
| 427 | |
| 393 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 428 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 394 ArgumentListNode* arguments = node->arguments(); | 429 ArgumentListNode* arguments = node->arguments(); |
| 395 int length = arguments->length(); | 430 int length = arguments->length(); |
| 396 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length + 1); | 431 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length + 1); |
| 397 | 432 |
| 398 ValueGraphVisitor for_receiver(owner(), temp_index()); | 433 ArgumentGraphVisitor for_receiver(owner(), temp_index()); |
| 399 node->receiver()->Visit(&for_receiver); | 434 node->receiver()->Visit(&for_receiver); |
| 400 Append(for_receiver); | 435 Append(for_receiver); |
| 401 CHECK_ALIVE(return); | 436 values->Add(for_receiver.value()); |
| 402 Value* receiver_value = for_receiver.value(); | |
| 403 temp_index_ = for_receiver.temp_index(); | |
| 404 if (receiver_value->IsConstant()) { | |
| 405 AddInstruction(new BindInstr(temp_index(), receiver_value)); | |
| 406 receiver_value = new TempVal(AllocateTempIndex()); | |
| 407 } | |
| 408 values->Add(receiver_value); | |
| 409 | 437 |
| 410 TranslateArgumentList(*arguments, values); | 438 TranslateArgumentList(*arguments, for_receiver.temp_index(), values); |
| 411 CHECK_ALIVE(return); | |
| 412 InstanceCallComp* call = | 439 InstanceCallComp* call = |
| 413 new InstanceCallComp(node->function_name().ToCString(), values); | 440 new InstanceCallComp(node, node->function_name(), values, |
| 441 arguments->names(), 1); | |
| 414 ReturnComputation(call); | 442 ReturnComputation(call); |
| 415 } | 443 } |
| 416 | 444 |
| 417 | 445 |
| 418 void EffectGraphVisitor::TranslateArgumentList( | |
| 419 const ArgumentListNode& node, ZoneGrowableArray<Value*>* values) { | |
| 420 int index = temp_index(); | |
| 421 for (intptr_t i = 0; i < node.length(); ++i) { | |
| 422 ValueGraphVisitor for_value(owner(), index); | |
| 423 node.NodeAt(i)->Visit(&for_value); | |
| 424 Append(for_value); | |
| 425 CHECK_ALIVE(return); | |
| 426 Value* argument_value = for_value.value(); | |
| 427 index = for_value.temp_index(); | |
| 428 if (argument_value->IsConstant()) { | |
| 429 AddInstruction(new BindInstr(index, argument_value)); | |
| 430 argument_value = new TempVal(index++); | |
| 431 } | |
| 432 values->Add(argument_value); | |
| 433 } | |
| 434 } | |
| 435 | |
| 436 // <Expression> ::= StaticCall { function: Function | 446 // <Expression> ::= StaticCall { function: Function |
| 437 // arguments: <ArgumentList> } | 447 // arguments: <ArgumentList> } |
| 438 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { | 448 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| 439 int length = node->arguments()->length(); | 449 int length = node->arguments()->length(); |
| 440 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length); | 450 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length); |
| 441 TranslateArgumentList(*node->arguments(), values); | 451 TranslateArgumentList(*node->arguments(), temp_index(), values); |
| 442 CHECK_ALIVE(return); | 452 StaticCallComp* call = new StaticCallComp(node, values); |
| 443 StaticCallComp* call = new StaticCallComp(node->function(), values); | |
| 444 ReturnComputation(call); | 453 ReturnComputation(call); |
| 445 } | 454 } |
| 446 | 455 |
| 447 | 456 |
| 448 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 457 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 449 Bailout("EffectGraphVisitor::VisitClosureCallNode"); | 458 Bailout("EffectGraphVisitor::VisitClosureCallNode"); |
| 450 } | 459 } |
| 451 | 460 |
| 452 | 461 |
| 453 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 462 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 653 | 662 |
| 654 | 663 |
| 655 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { | 664 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { |
| 656 OS::Print("AssertAssignable("); | 665 OS::Print("AssertAssignable("); |
| 657 comp->value()->Accept(this); | 666 comp->value()->Accept(this); |
| 658 OS::Print(", %s)", comp->type().ToCString()); | 667 OS::Print(", %s)", comp->type().ToCString()); |
| 659 } | 668 } |
| 660 | 669 |
| 661 | 670 |
| 662 void FlowGraphPrinter::VisitInstanceCall(InstanceCallComp* comp) { | 671 void FlowGraphPrinter::VisitInstanceCall(InstanceCallComp* comp) { |
| 663 OS::Print("InstanceCall(%s", comp->name()); | 672 OS::Print("InstanceCall(%s", comp->function_name().ToCString()); |
| 664 for (int i = 0; i < comp->ArgumentCount(); ++i) { | 673 for (int i = 0; i < comp->ArgumentCount(); ++i) { |
| 665 OS::Print(", "); | 674 OS::Print(", "); |
| 666 comp->ArgumentAt(i)->Accept(this); | 675 comp->ArgumentAt(i)->Accept(this); |
| 667 } | 676 } |
| 668 OS::Print(")"); | 677 OS::Print(")"); |
| 669 } | 678 } |
| 670 | 679 |
| 671 | 680 |
| 672 void FlowGraphPrinter::VisitStrictCompare(StrictCompareComp* comp) { | 681 void FlowGraphPrinter::VisitStrictCompare(StrictCompareComp* comp) { |
| 673 OS::Print("StrictCompare(%s, ", Token::Str(comp->kind())); | 682 OS::Print("StrictCompare(%s, ", Token::Str(comp->kind())); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 765 char* chars = reinterpret_cast<char*>( | 774 char* chars = reinterpret_cast<char*>( |
| 766 Isolate::Current()->current_zone()->Allocate(len)); | 775 Isolate::Current()->current_zone()->Allocate(len)); |
| 767 OS::SNPrint(chars, len, kFormat, function_name, reason); | 776 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 768 const Error& error = Error::Handle( | 777 const Error& error = Error::Handle( |
| 769 LanguageError::New(String::Handle(String::New(chars)))); | 778 LanguageError::New(String::Handle(String::New(chars)))); |
| 770 Isolate::Current()->long_jump_base()->Jump(1, error); | 779 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 771 } | 780 } |
| 772 | 781 |
| 773 | 782 |
| 774 } // namespace dart | 783 } // namespace dart |
| OLD | NEW |