| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 DISALLOW_COPY_AND_ASSIGN(HGraph); | 394 DISALLOW_COPY_AND_ASSIGN(HGraph); |
| 395 }; | 395 }; |
| 396 | 396 |
| 397 | 397 |
| 398 class HEnvironment: public ZoneObject { | 398 class HEnvironment: public ZoneObject { |
| 399 public: | 399 public: |
| 400 HEnvironment(HEnvironment* outer, | 400 HEnvironment(HEnvironment* outer, |
| 401 Scope* scope, | 401 Scope* scope, |
| 402 Handle<JSFunction> closure); | 402 Handle<JSFunction> closure); |
| 403 | 403 |
| 404 // Simple accessors. |
| 405 Handle<JSFunction> closure() const { return closure_; } |
| 406 const ZoneList<HValue*>* values() const { return &values_; } |
| 407 const ZoneList<int>* assigned_variables() const { |
| 408 return &assigned_variables_; |
| 409 } |
| 410 int parameter_count() const { return parameter_count_; } |
| 411 int local_count() const { return local_count_; } |
| 412 HEnvironment* outer() const { return outer_; } |
| 413 int pop_count() const { return pop_count_; } |
| 414 int push_count() const { return push_count_; } |
| 415 |
| 416 int ast_id() const { return ast_id_; } |
| 417 void set_ast_id(int id) { ast_id_ = id; } |
| 418 |
| 419 int length() const { return values_.length(); } |
| 420 |
| 404 void Bind(Variable* variable, HValue* value) { | 421 void Bind(Variable* variable, HValue* value) { |
| 405 Bind(IndexFor(variable), value); | 422 Bind(IndexFor(variable), value); |
| 406 | |
| 407 if (FLAG_trace_environment) { | |
| 408 PrintF("Slot index=%d name=%s\n", | |
| 409 variable->AsSlot()->index(), | |
| 410 *variable->name()->ToCString()); | |
| 411 } | |
| 412 } | 423 } |
| 413 | 424 |
| 414 void Bind(int index, HValue* value) { | 425 void Bind(int index, HValue* value); |
| 415 ASSERT(value != NULL); | |
| 416 if (!assigned_variables_.Contains(index)) { | |
| 417 assigned_variables_.Add(index); | |
| 418 } | |
| 419 values_[index] = value; | |
| 420 } | |
| 421 | 426 |
| 422 HValue* Lookup(Variable* variable) const { | 427 HValue* Lookup(Variable* variable) const { |
| 423 return Lookup(IndexFor(variable)); | 428 return Lookup(IndexFor(variable)); |
| 424 } | 429 } |
| 430 |
| 425 HValue* Lookup(int index) const { | 431 HValue* Lookup(int index) const { |
| 426 HValue* result = values_[index]; | 432 HValue* result = values_[index]; |
| 427 ASSERT(result != NULL); | 433 ASSERT(result != NULL); |
| 428 return result; | 434 return result; |
| 429 } | 435 } |
| 430 | 436 |
| 431 void Push(HValue* value) { | 437 void Push(HValue* value) { |
| 432 ASSERT(value != NULL); | 438 ASSERT(value != NULL); |
| 433 ++push_count_; | 439 ++push_count_; |
| 434 values_.Add(value); | 440 values_.Add(value); |
| 435 } | 441 } |
| 436 | 442 |
| 437 HValue* Top() const { return ExpressionStackAt(0); } | |
| 438 | |
| 439 HValue* ExpressionStackAt(int index_from_top) const { | |
| 440 int index = values_.length() - index_from_top - 1; | |
| 441 ASSERT(IsExpressionStackIndex(index)); | |
| 442 return values_[index]; | |
| 443 } | |
| 444 | |
| 445 void SetExpressionStackAt(int index_from_top, HValue* value) { | |
| 446 int index = values_.length() - index_from_top - 1; | |
| 447 ASSERT(IsExpressionStackIndex(index)); | |
| 448 values_[index] = value; | |
| 449 } | |
| 450 | |
| 451 HValue* Pop() { | 443 HValue* Pop() { |
| 452 ASSERT(!IsExpressionStackEmpty()); | 444 ASSERT(!ExpressionStackIsEmpty()); |
| 453 if (push_count_ > 0) { | 445 if (push_count_ > 0) { |
| 454 --push_count_; | 446 --push_count_; |
| 455 ASSERT(push_count_ >= 0); | |
| 456 } else { | 447 } else { |
| 457 ++pop_count_; | 448 ++pop_count_; |
| 458 } | 449 } |
| 459 return values_.RemoveLast(); | 450 return values_.RemoveLast(); |
| 460 } | 451 } |
| 461 | 452 |
| 462 void Drop(int count) { | 453 void Drop(int count); |
| 463 for (int i = 0; i < count; ++i) { | 454 |
| 464 Pop(); | 455 HValue* Top() const { return ExpressionStackAt(0); } |
| 465 } | 456 |
| 457 HValue* ExpressionStackAt(int index_from_top) const { |
| 458 int index = length() - index_from_top - 1; |
| 459 ASSERT(HasExpressionAt(index)); |
| 460 return values_[index]; |
| 466 } | 461 } |
| 467 | 462 |
| 468 Handle<JSFunction> closure() const { return closure_; } | 463 void SetExpressionStackAt(int index_from_top, HValue* value); |
| 469 | 464 |
| 470 // ID of the original AST node to identify deoptimization points. | |
| 471 int ast_id() const { return ast_id_; } | |
| 472 void set_ast_id(int id) { ast_id_ = id; } | |
| 473 | |
| 474 const ZoneList<HValue*>* values() const { return &values_; } | |
| 475 const ZoneList<int>* assigned_variables() const { | |
| 476 return &assigned_variables_; | |
| 477 } | |
| 478 int parameter_count() const { return parameter_count_; } | |
| 479 int local_count() const { return local_count_; } | |
| 480 int push_count() const { return push_count_; } | |
| 481 int pop_count() const { return pop_count_; } | |
| 482 int total_count() const { return values_.length(); } | |
| 483 HEnvironment* outer() const { return outer_; } | |
| 484 HEnvironment* Copy() const; | 465 HEnvironment* Copy() const; |
| 485 HEnvironment* CopyWithoutHistory() const; | 466 HEnvironment* CopyWithoutHistory() const; |
| 486 HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const; | 467 HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const; |
| 487 | 468 |
| 488 // Create an "inlined version" of this environment, where the original | 469 // Create an "inlined version" of this environment, where the original |
| 489 // environment is the outer environment but the top expression stack | 470 // environment is the outer environment but the top expression stack |
| 490 // elements are moved to an inner environment as parameters. If | 471 // elements are moved to an inner environment as parameters. If |
| 491 // is_speculative, the argument values are expected to be PushArgument | 472 // is_speculative, the argument values are expected to be PushArgument |
| 492 // instructions, otherwise they are the actual values. | 473 // instructions, otherwise they are the actual values. |
| 493 HEnvironment* CopyForInlining(Handle<JSFunction> target, | 474 HEnvironment* CopyForInlining(Handle<JSFunction> target, |
| 494 FunctionLiteral* function, | 475 FunctionLiteral* function, |
| 495 bool is_speculative, | 476 bool is_speculative, |
| 496 HConstant* undefined) const; | 477 HConstant* undefined) const; |
| 497 | 478 |
| 498 void AddIncomingEdge(HBasicBlock* block, HEnvironment* other); | 479 void AddIncomingEdge(HBasicBlock* block, HEnvironment* other); |
| 480 |
| 499 void ClearHistory() { | 481 void ClearHistory() { |
| 500 pop_count_ = 0; | 482 pop_count_ = 0; |
| 501 push_count_ = 0; | 483 push_count_ = 0; |
| 502 assigned_variables_.Clear(); | 484 assigned_variables_.Clear(); |
| 503 } | 485 } |
| 486 |
| 504 void SetValueAt(int index, HValue* value) { | 487 void SetValueAt(int index, HValue* value) { |
| 505 ASSERT(index < total_count()); | 488 ASSERT(index < length()); |
| 506 values_[index] = value; | 489 values_[index] = value; |
| 507 } | 490 } |
| 508 | 491 |
| 509 void PrintTo(StringStream* stream); | 492 void PrintTo(StringStream* stream); |
| 510 void PrintToStd(); | 493 void PrintToStd(); |
| 511 | 494 |
| 512 private: | 495 private: |
| 513 explicit HEnvironment(const HEnvironment* other); | 496 explicit HEnvironment(const HEnvironment* other); |
| 514 | 497 |
| 515 bool IsExpressionStackIndex(int index) const { | 498 // True if index is included in the expression stack part of the environment. |
| 516 return index >= parameter_count_ + local_count_; | 499 bool HasExpressionAt(int index) const; |
| 517 } | 500 |
| 518 bool IsExpressionStackEmpty() const { | 501 bool ExpressionStackIsEmpty() const; |
| 519 int length = values_.length(); | 502 |
| 520 int first_expression = parameter_count() + local_count(); | |
| 521 ASSERT(length >= first_expression); | |
| 522 return length == first_expression; | |
| 523 } | |
| 524 void Initialize(int parameter_count, int local_count, int stack_height); | 503 void Initialize(int parameter_count, int local_count, int stack_height); |
| 525 void Initialize(const HEnvironment* other); | 504 void Initialize(const HEnvironment* other); |
| 526 int VariableToIndex(Variable* var); | 505 |
| 527 int IndexFor(Variable* variable) const; | 506 // Map a variable to an environment index. Parameter indices are shifted |
| 507 // by 1 (receiver is parameter index -1 but environment index 0). |
| 508 // Stack-allocated local indices are shifted by the number of parameters. |
| 509 int IndexFor(Variable* variable) const { |
| 510 Slot* slot = variable->AsSlot(); |
| 511 ASSERT(slot != NULL && slot->IsStackAllocated()); |
| 512 int shift = (slot->type() == Slot::PARAMETER) ? 1 : parameter_count_; |
| 513 return slot->index() + shift; |
| 514 } |
| 528 | 515 |
| 529 Handle<JSFunction> closure_; | 516 Handle<JSFunction> closure_; |
| 530 // Value array [parameters] [locals] [temporaries]. | 517 // Value array [parameters] [locals] [temporaries]. |
| 531 ZoneList<HValue*> values_; | 518 ZoneList<HValue*> values_; |
| 532 ZoneList<int> assigned_variables_; | 519 ZoneList<int> assigned_variables_; |
| 533 int parameter_count_; | 520 int parameter_count_; |
| 534 int local_count_; | 521 int local_count_; |
| 535 HEnvironment* outer_; | 522 HEnvironment* outer_; |
| 536 int pop_count_; | 523 int pop_count_; |
| 537 int push_count_; | 524 int push_count_; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 560 | 547 |
| 561 protected: | 548 protected: |
| 562 AstContext(HGraphBuilder* owner, Expression::Context kind); | 549 AstContext(HGraphBuilder* owner, Expression::Context kind); |
| 563 virtual ~AstContext(); | 550 virtual ~AstContext(); |
| 564 | 551 |
| 565 HGraphBuilder* owner() const { return owner_; } | 552 HGraphBuilder* owner() const { return owner_; } |
| 566 | 553 |
| 567 // We want to be able to assert, in a context-specific way, that the stack | 554 // We want to be able to assert, in a context-specific way, that the stack |
| 568 // height makes sense when the context is filled. | 555 // height makes sense when the context is filled. |
| 569 #ifdef DEBUG | 556 #ifdef DEBUG |
| 570 int original_count_; | 557 int original_length_; |
| 571 #endif | 558 #endif |
| 572 | 559 |
| 573 private: | 560 private: |
| 574 HGraphBuilder* owner_; | 561 HGraphBuilder* owner_; |
| 575 Expression::Context kind_; | 562 Expression::Context kind_; |
| 576 AstContext* outer_; | 563 AstContext* outer_; |
| 577 }; | 564 }; |
| 578 | 565 |
| 579 | 566 |
| 580 class EffectContext: public AstContext { | 567 class EffectContext: public AstContext { |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1061 const char* filename_; | 1048 const char* filename_; |
| 1062 HeapStringAllocator string_allocator_; | 1049 HeapStringAllocator string_allocator_; |
| 1063 StringStream trace_; | 1050 StringStream trace_; |
| 1064 int indent_; | 1051 int indent_; |
| 1065 }; | 1052 }; |
| 1066 | 1053 |
| 1067 | 1054 |
| 1068 } } // namespace v8::internal | 1055 } } // namespace v8::internal |
| 1069 | 1056 |
| 1070 #endif // V8_HYDROGEN_H_ | 1057 #endif // V8_HYDROGEN_H_ |
| OLD | NEW |