| OLD | NEW |
| 1 // Copyright 2010 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 382 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 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 912 HValueMapListElement* array_; // Primary store - contains the first value | 899 HValueMapListElement* array_; // Primary store - contains the first value |
| 913 // with a given hash. Colliding elements are stored in linked lists. | 900 // with a given hash. Colliding elements are stored in linked lists. |
| 914 HValueMapListElement* lists_; // The linked lists containing hash collisions. | 901 HValueMapListElement* lists_; // The linked lists containing hash collisions. |
| 915 int free_list_head_; // Unused elements in lists_ are on the free list. | 902 int free_list_head_; // Unused elements in lists_ are on the free list. |
| 916 }; | 903 }; |
| 917 | 904 |
| 918 | 905 |
| 919 class HStatistics: public Malloced { | 906 class HStatistics: public Malloced { |
| 920 public: | 907 public: |
| 921 void Print(); | 908 void Print(); |
| 922 void SaveTiming(const char* name, int64_t ticks); | 909 void SaveTiming(const char* name, int64_t ticks, unsigned size); |
| 923 static HStatistics* Instance() { | 910 static HStatistics* Instance() { |
| 924 static SetOncePointer<HStatistics> instance; | 911 static SetOncePointer<HStatistics> instance; |
| 925 if (!instance.is_set()) { | 912 if (!instance.is_set()) { |
| 926 instance.set(new HStatistics()); | 913 instance.set(new HStatistics()); |
| 927 } | 914 } |
| 928 return instance.get(); | 915 return instance.get(); |
| 929 } | 916 } |
| 930 | 917 |
| 931 private: | 918 private: |
| 932 | 919 |
| 933 HStatistics() : timing_(5), names_(5), total_(0), full_code_gen_(0) { } | 920 HStatistics() |
| 921 : timing_(5), |
| 922 names_(5), |
| 923 sizes_(5), |
| 924 total_(0), |
| 925 total_size_(0), |
| 926 full_code_gen_(0) { } |
| 934 | 927 |
| 935 List<int64_t> timing_; | 928 List<int64_t> timing_; |
| 936 List<const char*> names_; | 929 List<const char*> names_; |
| 930 List<unsigned> sizes_; |
| 937 int64_t total_; | 931 int64_t total_; |
| 932 unsigned total_size_; |
| 938 int64_t full_code_gen_; | 933 int64_t full_code_gen_; |
| 939 }; | 934 }; |
| 940 | 935 |
| 941 | 936 |
| 942 class HPhase BASE_EMBEDDED { | 937 class HPhase BASE_EMBEDDED { |
| 943 public: | 938 public: |
| 944 static const char* const kFullCodeGen; | 939 static const char* const kFullCodeGen; |
| 945 static const char* const kTotal; | 940 static const char* const kTotal; |
| 946 | 941 |
| 947 explicit HPhase(const char* name) { Begin(name, NULL, NULL, NULL); } | 942 explicit HPhase(const char* name) { Begin(name, NULL, NULL, NULL); } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 964 HGraph* graph, | 959 HGraph* graph, |
| 965 LChunk* chunk, | 960 LChunk* chunk, |
| 966 LAllocator* allocator); | 961 LAllocator* allocator); |
| 967 void End() const; | 962 void End() const; |
| 968 | 963 |
| 969 int64_t start_; | 964 int64_t start_; |
| 970 const char* name_; | 965 const char* name_; |
| 971 HGraph* graph_; | 966 HGraph* graph_; |
| 972 LChunk* chunk_; | 967 LChunk* chunk_; |
| 973 LAllocator* allocator_; | 968 LAllocator* allocator_; |
| 969 unsigned start_allocation_size_; |
| 974 }; | 970 }; |
| 975 | 971 |
| 976 | 972 |
| 977 class HTracer: public Malloced { | 973 class HTracer: public Malloced { |
| 978 public: | 974 public: |
| 979 void TraceCompilation(FunctionLiteral* function); | 975 void TraceCompilation(FunctionLiteral* function); |
| 980 void TraceHydrogen(const char* name, HGraph* graph); | 976 void TraceHydrogen(const char* name, HGraph* graph); |
| 981 void TraceLithium(const char* name, LChunk* chunk); | 977 void TraceLithium(const char* name, LChunk* chunk); |
| 982 void TraceLiveRanges(const char* name, LAllocator* allocator); | 978 void TraceLiveRanges(const char* name, LAllocator* allocator); |
| 983 | 979 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1061 const char* filename_; | 1057 const char* filename_; |
| 1062 HeapStringAllocator string_allocator_; | 1058 HeapStringAllocator string_allocator_; |
| 1063 StringStream trace_; | 1059 StringStream trace_; |
| 1064 int indent_; | 1060 int indent_; |
| 1065 }; | 1061 }; |
| 1066 | 1062 |
| 1067 | 1063 |
| 1068 } } // namespace v8::internal | 1064 } } // namespace v8::internal |
| 1069 | 1065 |
| 1070 #endif // V8_HYDROGEN_H_ | 1066 #endif // V8_HYDROGEN_H_ |
| OLD | NEW |