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

Side by Side Diff: src/hydrogen.h

Issue 6529055: [Isolates] Merge crankshaft (r5922 from bleeding_edge). (Closed)
Patch Set: Win32 port Created 9 years, 10 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/heap-inl.h ('k') | src/hydrogen.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #ifndef V8_HYDROGEN_H_
29 #define V8_HYDROGEN_H_
30
31 #include "v8.h"
32
33 #include "ast.h"
34 #include "compiler.h"
35 #include "data-flow.h"
36 #include "hydrogen-instructions.h"
37 #include "zone.h"
38
39 namespace v8 {
40 namespace internal {
41
42 // Forward declarations.
43 class HEnvironment;
44 class HGraph;
45 class HLoopInformation;
46 class HTracer;
47 class LAllocator;
48 class LChunk;
49 class LiveRange;
50
51
52 class HBasicBlock: public ZoneObject {
53 public:
54 explicit HBasicBlock(HGraph* graph);
55 virtual ~HBasicBlock() { }
56
57 // Simple accessors.
58 int block_id() const { return block_id_; }
59 void set_block_id(int id) { block_id_ = id; }
60 HGraph* graph() const { return graph_; }
61 const ZoneList<HPhi*>* phis() const { return &phis_; }
62 HInstruction* first() const { return first_; }
63 HInstruction* GetLastInstruction();
64 HControlInstruction* end() const { return end_; }
65 HLoopInformation* loop_information() const { return loop_information_; }
66 const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; }
67 bool HasPredecessor() const { return predecessors_.length() > 0; }
68 const ZoneList<HBasicBlock*>* dominated_blocks() const {
69 return &dominated_blocks_;
70 }
71 const ZoneList<int>* deleted_phis() const {
72 return &deleted_phis_;
73 }
74 void RecordDeletedPhi(int merge_index) {
75 deleted_phis_.Add(merge_index);
76 }
77 HBasicBlock* dominator() const { return dominator_; }
78 HEnvironment* last_environment() const { return last_environment_; }
79 int argument_count() const { return argument_count_; }
80 void set_argument_count(int count) { argument_count_ = count; }
81 int first_instruction_index() const { return first_instruction_index_; }
82 void set_first_instruction_index(int index) {
83 first_instruction_index_ = index;
84 }
85 int last_instruction_index() const { return last_instruction_index_; }
86 void set_last_instruction_index(int index) {
87 last_instruction_index_ = index;
88 }
89
90 void AttachLoopInformation();
91 void DetachLoopInformation();
92 bool IsLoopHeader() const { return loop_information() != NULL; }
93 bool IsStartBlock() const { return block_id() == 0; }
94 void PostProcessLoopHeader(IterationStatement* stmt);
95
96 bool IsFinished() const { return end_ != NULL; }
97 void AddPhi(HPhi* phi);
98 void RemovePhi(HPhi* phi);
99 void AddInstruction(HInstruction* instr);
100 bool Dominates(HBasicBlock* other) const;
101
102 void SetInitialEnvironment(HEnvironment* env);
103 void ClearEnvironment() { last_environment_ = NULL; }
104 bool HasEnvironment() const { return last_environment_ != NULL; }
105 void UpdateEnvironment(HEnvironment* env) { last_environment_ = env; }
106 HBasicBlock* parent_loop_header() const {
107 if (!HasParentLoopHeader()) return NULL;
108 return parent_loop_header_.get();
109 }
110
111 void set_parent_loop_header(HBasicBlock* block) {
112 parent_loop_header_.set(block);
113 }
114
115 bool HasParentLoopHeader() const { return parent_loop_header_.is_set(); }
116
117 void SetJoinId(int id);
118
119 void Finish(HControlInstruction* last);
120 void Goto(HBasicBlock* block, bool include_stack_check = false);
121
122 int PredecessorIndexOf(HBasicBlock* predecessor) const;
123 void AddSimulate(int id) { AddInstruction(CreateSimulate(id)); }
124 void AssignCommonDominator(HBasicBlock* other);
125
126 // Add the inlined function exit sequence, adding an HLeaveInlined
127 // instruction and updating the bailout environment.
128 void AddLeaveInlined(HValue* return_value, HBasicBlock* target);
129
130 // If a target block is tagged as an inline function return, all
131 // predecessors should contain the inlined exit sequence:
132 //
133 // LeaveInlined
134 // Simulate (caller's environment)
135 // Goto (target block)
136 bool IsInlineReturnTarget() const { return is_inline_return_target_; }
137 void MarkAsInlineReturnTarget() { is_inline_return_target_ = true; }
138
139 // If this block is a successor of a branch, his flags tells whether the
140 // preceding branch was inverted or not.
141 bool inverted() { return inverted_; }
142 void set_inverted(bool b) { inverted_ = b; }
143
144 HBasicBlock* deopt_predecessor() { return deopt_predecessor_; }
145 void set_deopt_predecessor(HBasicBlock* block) { deopt_predecessor_ = block; }
146
147 Handle<Object> cond() { return cond_; }
148 void set_cond(Handle<Object> value) { cond_ = value; }
149
150 #ifdef DEBUG
151 void Verify();
152 #endif
153
154 private:
155 void RegisterPredecessor(HBasicBlock* pred);
156 void AddDominatedBlock(HBasicBlock* block);
157
158 HSimulate* CreateSimulate(int id);
159
160 int block_id_;
161 HGraph* graph_;
162 ZoneList<HPhi*> phis_;
163 HInstruction* first_;
164 HInstruction* last_; // Last non-control instruction of the block.
165 HControlInstruction* end_;
166 HLoopInformation* loop_information_;
167 ZoneList<HBasicBlock*> predecessors_;
168 HBasicBlock* dominator_;
169 ZoneList<HBasicBlock*> dominated_blocks_;
170 HEnvironment* last_environment_;
171 // Outgoing parameter count at block exit, set during lithium translation.
172 int argument_count_;
173 // Instruction indices into the lithium code stream.
174 int first_instruction_index_;
175 int last_instruction_index_;
176 ZoneList<int> deleted_phis_;
177 SetOncePointer<HBasicBlock> parent_loop_header_;
178 bool is_inline_return_target_;
179 bool inverted_;
180 HBasicBlock* deopt_predecessor_;
181 Handle<Object> cond_;
182 };
183
184
185 class HLoopInformation: public ZoneObject {
186 public:
187 explicit HLoopInformation(HBasicBlock* loop_header)
188 : back_edges_(4), loop_header_(loop_header), blocks_(8) {
189 blocks_.Add(loop_header);
190 }
191 virtual ~HLoopInformation() {}
192
193 const ZoneList<HBasicBlock*>* back_edges() const { return &back_edges_; }
194 const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
195 HBasicBlock* loop_header() const { return loop_header_; }
196 HBasicBlock* GetLastBackEdge() const;
197 void RegisterBackEdge(HBasicBlock* block);
198
199 private:
200 void AddBlock(HBasicBlock* block);
201
202 ZoneList<HBasicBlock*> back_edges_;
203 HBasicBlock* loop_header_;
204 ZoneList<HBasicBlock*> blocks_;
205 };
206
207
208 class HSubgraph: public ZoneObject {
209 public:
210 explicit HSubgraph(HGraph* graph)
211 : graph_(graph),
212 entry_block_(NULL),
213 exit_block_(NULL),
214 break_continue_info_(4) {
215 }
216
217 HGraph* graph() const { return graph_; }
218 HEnvironment* environment() const {
219 ASSERT(HasExit());
220 return exit_block_->last_environment();
221 }
222
223 bool HasExit() const { return exit_block_ != NULL; }
224
225 void PreProcessOsrEntry(IterationStatement* statement);
226
227 void AppendOptional(HSubgraph* graph,
228 bool on_true_branch,
229 HValue* boolean_value);
230 void AppendJoin(HSubgraph* then_graph, HSubgraph* else_graph, AstNode* node);
231 void AppendWhile(HSubgraph* condition,
232 HSubgraph* body,
233 IterationStatement* statement,
234 HSubgraph* continue_subgraph,
235 HSubgraph* exit);
236 void AppendDoWhile(HSubgraph* body,
237 IterationStatement* statement,
238 HSubgraph* go_back,
239 HSubgraph* exit);
240 void AppendEndless(HSubgraph* body, IterationStatement* statement);
241 void Append(HSubgraph* next, BreakableStatement* statement);
242 void ResolveContinue(IterationStatement* statement);
243 HBasicBlock* BundleBreak(BreakableStatement* statement);
244 HBasicBlock* BundleContinue(IterationStatement* statement);
245 HBasicBlock* BundleBreakContinue(BreakableStatement* statement,
246 bool is_continue,
247 int join_id);
248 HBasicBlock* JoinBlocks(HBasicBlock* a, HBasicBlock* b, int id);
249
250 void FinishExit(HControlInstruction* instruction);
251 void FinishBreakContinue(BreakableStatement* target, bool is_continue);
252 void Initialize(HBasicBlock* block) {
253 ASSERT(entry_block_ == NULL);
254 entry_block_ = block;
255 exit_block_ = block;
256 }
257 HBasicBlock* entry_block() const { return entry_block_; }
258 HBasicBlock* exit_block() const { return exit_block_; }
259 void set_exit_block(HBasicBlock* block) {
260 exit_block_ = block;
261 }
262
263 void ConnectExitTo(HBasicBlock* other, bool include_stack_check = false) {
264 if (HasExit()) {
265 exit_block()->Goto(other, include_stack_check);
266 }
267 }
268
269 void AddBreakContinueInfo(HSubgraph* other) {
270 break_continue_info_.AddAll(other->break_continue_info_);
271 }
272
273 protected:
274 class BreakContinueInfo: public ZoneObject {
275 public:
276 BreakContinueInfo(BreakableStatement* target, HBasicBlock* block,
277 bool is_continue)
278 : target_(target), block_(block), continue_(is_continue) {}
279 BreakableStatement* target() const { return target_; }
280 HBasicBlock* block() const { return block_; }
281 bool is_continue() const { return continue_; }
282 bool IsResolved() const { return block_ == NULL; }
283 void Resolve() { block_ = NULL; }
284
285 private:
286 BreakableStatement* target_;
287 HBasicBlock* block_;
288 bool continue_;
289 };
290
291 const ZoneList<BreakContinueInfo*>* break_continue_info() const {
292 return &break_continue_info_;
293 }
294
295 HGraph* graph_; // The graph this is a subgraph of.
296 HBasicBlock* entry_block_;
297 HBasicBlock* exit_block_;
298
299 private:
300 ZoneList<BreakContinueInfo*> break_continue_info_;
301 };
302
303
304 class HGraph: public HSubgraph {
305 public:
306 explicit HGraph(CompilationInfo* info);
307
308 CompilationInfo* info() const { return info_; }
309 const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
310 const ZoneList<HPhi*>* phi_list() const { return phi_list_; }
311 Handle<String> debug_name() const { return info_->function()->debug_name(); }
312 HEnvironment* start_environment() const { return start_environment_; }
313
314 void InitializeInferredTypes();
315 void InsertTypeConversions();
316 void InsertRepresentationChanges();
317 bool ProcessArgumentsObject();
318 void EliminateRedundantPhis();
319 void Canonicalize();
320 void OrderBlocks();
321 void AssignDominators();
322
323 // Returns false if there are phi-uses of the arguments-object
324 // which are not supported by the optimizing compiler.
325 bool CollectPhis();
326
327 Handle<Code> Compile();
328
329 void set_undefined_constant(HConstant* constant) {
330 undefined_constant_.set(constant);
331 }
332 HConstant* GetConstantUndefined() const { return undefined_constant_.get(); }
333 HConstant* GetConstant1();
334 HConstant* GetConstantMinus1();
335 HConstant* GetConstantTrue();
336 HConstant* GetConstantFalse();
337
338 HBasicBlock* CreateBasicBlock();
339 HArgumentsObject* GetArgumentsObject() const {
340 return arguments_object_.get();
341 }
342 bool HasArgumentsObject() const { return arguments_object_.is_set(); }
343
344 void SetArgumentsObject(HArgumentsObject* object) {
345 arguments_object_.set(object);
346 }
347
348 // True iff. we are compiling for OSR and the statement is the entry.
349 bool HasOsrEntryAt(IterationStatement* statement);
350
351 int GetMaximumValueID() const { return values_.length(); }
352 int GetNextBlockID() { return next_block_id_++; }
353 int GetNextValueID(HValue* value) {
354 values_.Add(value);
355 return values_.length() - 1;
356 }
357 HValue* LookupValue(int id) const {
358 if (id >= 0 && id < values_.length()) return values_[id];
359 return NULL;
360 }
361
362 #ifdef DEBUG
363 void Verify() const;
364 #endif
365
366 private:
367 void Postorder(HBasicBlock* block,
368 BitVector* visited,
369 ZoneList<HBasicBlock*>* order,
370 HBasicBlock* loop_header);
371 void PostorderLoopBlocks(HLoopInformation* loop,
372 BitVector* visited,
373 ZoneList<HBasicBlock*>* order,
374 HBasicBlock* loop_header);
375 HConstant* GetConstant(SetOncePointer<HConstant>* pointer,
376 Object* value);
377
378 void InsertTypeConversions(HInstruction* instr);
379 void PropagateMinusZeroChecks(HValue* value, BitVector* visited);
380 void InsertRepresentationChangeForUse(HValue* value,
381 HValue* use,
382 Representation to,
383 bool truncating);
384 void InsertRepresentationChanges(HValue* current);
385 void InferTypes(ZoneList<HValue*>* worklist);
386 void InitializeInferredTypes(int from_inclusive, int to_inclusive);
387 void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor);
388
389 int next_block_id_;
390 CompilationInfo* info_;
391 HEnvironment* start_environment_;
392 ZoneList<HBasicBlock*> blocks_;
393 ZoneList<HValue*> values_;
394 ZoneList<HPhi*>* phi_list_;
395 SetOncePointer<HConstant> undefined_constant_;
396 SetOncePointer<HConstant> constant_1_;
397 SetOncePointer<HConstant> constant_minus1_;
398 SetOncePointer<HConstant> constant_true_;
399 SetOncePointer<HConstant> constant_false_;
400 SetOncePointer<HArgumentsObject> arguments_object_;
401
402 friend class HSubgraph;
403
404 DISALLOW_COPY_AND_ASSIGN(HGraph);
405 };
406
407
408 class HEnvironment: public ZoneObject {
409 public:
410 HEnvironment(HEnvironment* outer,
411 Scope* scope,
412 Handle<JSFunction> closure);
413
414 void Bind(Variable* variable, HValue* value) {
415 Bind(IndexFor(variable), value);
416
417 if (FLAG_trace_environment) {
418 PrintF("Slot index=%d name=%s\n",
419 variable->AsSlot()->index(),
420 *variable->name()->ToCString());
421 }
422 }
423
424 void Bind(int index, HValue* value) {
425 ASSERT(value != NULL);
426 if (!assigned_variables_.Contains(index)) {
427 assigned_variables_.Add(index);
428 }
429 values_[index] = value;
430 }
431
432 HValue* Lookup(Variable* variable) const {
433 return Lookup(IndexFor(variable));
434 }
435 HValue* Lookup(int index) const {
436 HValue* result = values_[index];
437 ASSERT(result != NULL);
438 return result;
439 }
440
441 void Push(HValue* value) {
442 ASSERT(value != NULL);
443 ++push_count_;
444 values_.Add(value);
445 }
446
447 HValue* Top() const { return ExpressionStackAt(0); }
448
449 HValue* ExpressionStackAt(int index_from_top) const {
450 int index = values_.length() - index_from_top - 1;
451 ASSERT(IsExpressionStackIndex(index));
452 return values_[index];
453 }
454
455 void SetExpressionStackAt(int index_from_top, HValue* value) {
456 int index = values_.length() - index_from_top - 1;
457 ASSERT(IsExpressionStackIndex(index));
458 values_[index] = value;
459 }
460
461 HValue* Pop() {
462 ASSERT(!IsExpressionStackEmpty());
463 if (push_count_ > 0) {
464 --push_count_;
465 ASSERT(push_count_ >= 0);
466 } else {
467 ++pop_count_;
468 }
469 return values_.RemoveLast();
470 }
471
472 void Drop(int count) {
473 for (int i = 0; i < count; ++i) {
474 Pop();
475 }
476 }
477
478 Handle<JSFunction> closure() const { return closure_; }
479
480 // ID of the original AST node to identify deoptimization points.
481 int ast_id() const { return ast_id_; }
482 void set_ast_id(int id) { ast_id_ = id; }
483
484 const ZoneList<HValue*>* values() const { return &values_; }
485 const ZoneList<int>* assigned_variables() const {
486 return &assigned_variables_;
487 }
488 int parameter_count() const { return parameter_count_; }
489 int local_count() const { return local_count_; }
490 int push_count() const { return push_count_; }
491 int pop_count() const { return pop_count_; }
492 int total_count() const { return values_.length(); }
493 HEnvironment* outer() const { return outer_; }
494 HEnvironment* Copy() const;
495 HEnvironment* CopyWithoutHistory() const;
496 HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const;
497
498 // Create an "inlined version" of this environment, where the original
499 // environment is the outer environment but the top expression stack
500 // elements are moved to an inner environment as parameters. If
501 // is_speculative, the argument values are expected to be PushArgument
502 // instructions, otherwise they are the actual values.
503 HEnvironment* CopyForInlining(Handle<JSFunction> target,
504 FunctionLiteral* function,
505 bool is_speculative,
506 HConstant* undefined) const;
507
508 void AddIncomingEdge(HBasicBlock* block, HEnvironment* other);
509 void ClearHistory() {
510 pop_count_ = 0;
511 push_count_ = 0;
512 assigned_variables_.Clear();
513 }
514 void SetValueAt(int index, HValue* value) {
515 ASSERT(index < total_count());
516 values_[index] = value;
517 }
518
519 void PrintTo(StringStream* stream);
520 void PrintToStd();
521
522 private:
523 explicit HEnvironment(const HEnvironment* other);
524
525 bool IsExpressionStackIndex(int index) const {
526 return index >= parameter_count_ + local_count_;
527 }
528 bool IsExpressionStackEmpty() const {
529 int length = values_.length();
530 int first_expression = parameter_count() + local_count();
531 ASSERT(length >= first_expression);
532 return length == first_expression;
533 }
534 void Initialize(int parameter_count, int local_count, int stack_height);
535 void Initialize(const HEnvironment* other);
536 int VariableToIndex(Variable* var);
537 int IndexFor(Variable* variable) const;
538
539 Handle<JSFunction> closure_;
540 // Value array [parameters] [locals] [temporaries].
541 ZoneList<HValue*> values_;
542 ZoneList<int> assigned_variables_;
543 int parameter_count_;
544 int local_count_;
545 HEnvironment* outer_;
546 int pop_count_;
547 int push_count_;
548 int ast_id_;
549 };
550
551
552 class HGraphBuilder;
553
554 class AstContext {
555 public:
556 bool IsEffect() const { return kind_ == Expression::kEffect; }
557 bool IsValue() const { return kind_ == Expression::kValue; }
558 bool IsTest() const { return kind_ == Expression::kTest; }
559
560 protected:
561 AstContext(HGraphBuilder* owner, Expression::Context kind);
562 virtual ~AstContext();
563
564 private:
565 HGraphBuilder* owner_;
566 Expression::Context kind_;
567 AstContext* outer_;
568 };
569
570
571 class EffectContext: public AstContext {
572 public:
573 explicit EffectContext(HGraphBuilder* owner)
574 : AstContext(owner, Expression::kEffect) {
575 }
576 };
577
578
579 class ValueContext: public AstContext {
580 public:
581 explicit ValueContext(HGraphBuilder* owner)
582 : AstContext(owner, Expression::kValue) {
583 }
584 };
585
586
587 class TestContext: public AstContext {
588 public:
589 TestContext(HGraphBuilder* owner,
590 HBasicBlock* if_true,
591 HBasicBlock* if_false,
592 bool invert_true,
593 bool invert_false)
594 : AstContext(owner, Expression::kTest),
595 if_true_(if_true),
596 if_false_(if_false),
597 invert_true_(invert_true),
598 invert_false_(invert_false) {
599 }
600
601 static TestContext* cast(AstContext* context) {
602 ASSERT(context->IsTest());
603 return reinterpret_cast<TestContext*>(context);
604 }
605
606 HBasicBlock* if_true() const { return if_true_; }
607 HBasicBlock* if_false() const { return if_false_; }
608
609 bool invert_true() { return invert_true_; }
610 bool invert_false() { return invert_false_; }
611
612 private:
613 HBasicBlock* if_true_;
614 HBasicBlock* if_false_;
615 bool invert_true_;
616 bool invert_false_;
617 };
618
619
620 class HGraphBuilder: public AstVisitor {
621 public:
622 explicit HGraphBuilder(TypeFeedbackOracle* oracle)
623 : oracle_(oracle),
624 graph_(NULL),
625 current_subgraph_(NULL),
626 peeled_statement_(NULL),
627 ast_context_(NULL),
628 call_context_(NULL),
629 function_return_(NULL),
630 inlined_count_(0) { }
631
632 HGraph* CreateGraph(CompilationInfo* info);
633
634 private:
635 // Type of a member function that generates inline code for a native function.
636 typedef void (HGraphBuilder::*InlineFunctionGenerator)(int argument_count);
637
638 // Forward declarations for inner scope classes.
639 class SubgraphScope;
640
641 static const InlineFunctionGenerator kInlineFunctionGenerators[];
642
643 static const int kMaxCallPolymorphism = 4;
644 static const int kMaxLoadPolymorphism = 4;
645 static const int kMaxStorePolymorphism = 4;
646
647 static const int kMaxInlinedNodes = 196;
648 static const int kMaxInlinedSize = 196;
649 static const int kMaxSourceSize = 600;
650
651 // Simple accessors.
652 TypeFeedbackOracle* oracle() const { return oracle_; }
653 HGraph* graph() const { return graph_; }
654 HSubgraph* subgraph() const { return current_subgraph_; }
655 AstContext* ast_context() const { return ast_context_; }
656 void set_ast_context(AstContext* context) { ast_context_ = context; }
657 AstContext* call_context() const { return call_context_; }
658 HBasicBlock* function_return() const { return function_return_; }
659 HEnvironment* environment() const { return subgraph()->environment(); }
660
661 HBasicBlock* CurrentBlock() const { return subgraph()->exit_block(); }
662
663 // Generators for inline runtime functions.
664 #define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize) \
665 void Generate##Name(int argument_count);
666
667 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION)
668 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION)
669 #undef INLINE_FUNCTION_GENERATOR_DECLARATION
670
671 void Bailout(const char* reason);
672
673 void AppendPeeledWhile(IterationStatement* stmt,
674 HSubgraph* cond_graph,
675 HSubgraph* body_graph,
676 HSubgraph* exit_graph);
677
678 void AddToSubgraph(HSubgraph* graph, ZoneList<Statement*>* stmts);
679 void AddToSubgraph(HSubgraph* graph, Statement* stmt);
680 void AddToSubgraph(HSubgraph* graph, Expression* expr);
681 void AddConditionToSubgraph(HSubgraph* subgraph,
682 Expression* expr,
683 HSubgraph* true_graph,
684 HSubgraph* false_graph);
685
686 void Push(HValue* value) { environment()->Push(value); }
687 HValue* Pop() { return environment()->Pop(); }
688 HValue* Top() const { return environment()->Top(); }
689 void Drop(int n) { environment()->Drop(n); }
690 void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); }
691
692 void VisitForValue(Expression* expr);
693 void VisitForEffect(Expression* expr);
694 void VisitForControl(Expression* expr,
695 HBasicBlock* true_block,
696 HBasicBlock* false_block,
697 bool invert_true,
698 bool invert_false);
699
700 // Visit an expression in a 'condition' context, i.e., in a control
701 // context but not a subexpression of logical and, or, or not.
702 void VisitCondition(Expression* expr,
703 HBasicBlock* true_graph,
704 HBasicBlock* false_graph,
705 bool invert_true,
706 bool invert_false);
707 // Visit an argument and wrap it in a PushArgument instruction.
708 HValue* VisitArgument(Expression* expr);
709 void VisitArgumentList(ZoneList<Expression*>* arguments);
710
711 HInstruction* AddInstruction(HInstruction* instr);
712 void AddSimulate(int id);
713 void AddPhi(HPhi* phi);
714
715 void PushAndAdd(HInstruction* instr);
716 void PushAndAdd(HInstruction* instr, int position);
717
718 void PushArgumentsForStubCall(int argument_count);
719
720 // Initialize the arguments to the call based on then environment, add it
721 // to the graph, and drop the arguments from the environment.
722 void ProcessCall(HCall* call, int source_position);
723
724 void AssumeRepresentation(HValue* value, Representation r);
725 static Representation ToRepresentation(TypeInfo info);
726
727 void SetupScope(Scope* scope);
728 virtual void VisitStatements(ZoneList<Statement*>* statements);
729
730 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
731 AST_NODE_LIST(DECLARE_VISIT)
732 #undef DECLARE_VISIT
733
734 bool ShouldPeel(HSubgraph* cond, HSubgraph* body);
735
736 HBasicBlock* CreateBasicBlock(HEnvironment* env);
737 HSubgraph* CreateEmptySubgraph();
738 HSubgraph* CreateGotoSubgraph(HEnvironment* env);
739 HSubgraph* CreateBranchSubgraph(HEnvironment* env);
740 HSubgraph* CreateLoopHeaderSubgraph(HEnvironment* env);
741 HSubgraph* CreateInlinedSubgraph(HEnvironment* outer,
742 Handle<JSFunction> target,
743 FunctionLiteral* function);
744
745 // Helpers for flow graph construction.
746 void LookupGlobalPropertyCell(VariableProxy* expr,
747 LookupResult* lookup,
748 bool is_store);
749
750 bool TryArgumentsAccess(Property* expr);
751 bool TryCallApply(Call* expr);
752 bool TryInline(Call* expr);
753 bool TryMathFunctionInline(Call* expr);
754 void TraceInline(Handle<JSFunction> target, bool result);
755
756 void HandleGlobalVariableAssignment(VariableProxy* proxy,
757 HValue* value,
758 int position);
759 void HandleGlobalVariableLoad(VariableProxy* expr);
760 void HandlePropertyAssignment(Assignment* expr);
761 void HandleCompoundAssignment(Assignment* expr);
762 void HandlePolymorphicLoadNamedField(Property* expr,
763 HValue* object,
764 ZoneMapList* types,
765 Handle<String> name);
766 void HandlePolymorphicStoreNamedField(Assignment* expr,
767 HValue* object,
768 HValue* value,
769 ZoneMapList* types,
770 Handle<String> name);
771 void HandlePolymorphicCallNamed(Call* expr,
772 HValue* receiver,
773 ZoneMapList* types,
774 Handle<String> name);
775
776 HInstruction* BuildBinaryOperation(BinaryOperation* expr,
777 HValue* left,
778 HValue* right);
779 HInstruction* BuildIncrement(HValue* value, bool increment);
780 HInstruction* BuildLoadNamedField(HValue* object,
781 Property* expr,
782 Handle<Map> type,
783 LookupResult* result,
784 bool smi_and_map_check);
785 HInstruction* BuildLoadNamedGeneric(HValue* object, Property* expr);
786 HInstruction* BuildLoadKeyedFastElement(HValue* object,
787 HValue* key,
788 Property* expr);
789 HInstruction* BuildLoadKeyedGeneric(HValue* object,
790 HValue* key);
791
792 HInstruction* BuildLoadNamed(HValue* object,
793 Property* prop,
794 Handle<Map> map,
795 Handle<String> name);
796 HInstruction* BuildStoreNamed(HValue* object,
797 HValue* value,
798 Expression* expr);
799 HInstruction* BuildStoreNamedField(HValue* object,
800 Handle<String> name,
801 HValue* value,
802 Handle<Map> type,
803 LookupResult* lookup,
804 bool smi_and_map_check);
805 HInstruction* BuildStoreNamedGeneric(HValue* object,
806 Handle<String> name,
807 HValue* value);
808 HInstruction* BuildStoreKeyedGeneric(HValue* object,
809 HValue* key,
810 HValue* value);
811
812 HInstruction* BuildStoreKeyedFastElement(HValue* object,
813 HValue* key,
814 HValue* val,
815 Expression* expr);
816
817 HCompare* BuildSwitchCompare(HSubgraph* subgraph,
818 HValue* switch_value,
819 CaseClause* clause);
820
821 void AddCheckConstantFunction(Call* expr,
822 HValue* receiver,
823 Handle<Map> receiver_map,
824 bool smi_and_map_check);
825
826
827 HBasicBlock* BuildTypeSwitch(ZoneMapList* maps,
828 ZoneList<HSubgraph*>* subgraphs,
829 HValue* receiver,
830 int join_id);
831
832 TypeFeedbackOracle* oracle_;
833 HGraph* graph_;
834 HSubgraph* current_subgraph_;
835 IterationStatement* peeled_statement_;
836 // Expression context of the currently visited subexpression. NULL when
837 // visiting statements.
838 AstContext* ast_context_;
839
840 // During function inlining, expression context of the call being
841 // inlined. NULL when not inlining.
842 AstContext* call_context_;
843
844 // When inlining a call in an effect or value context, the return
845 // block. NULL otherwise. When inlining a call in a test context, there
846 // are a pair of target blocks in the call context.
847 HBasicBlock* function_return_;
848
849 int inlined_count_;
850
851 friend class AstContext; // Pushes and pops the AST context stack.
852
853 DISALLOW_COPY_AND_ASSIGN(HGraphBuilder);
854 };
855
856
857 class HValueMap: public ZoneObject {
858 public:
859 HValueMap()
860 : array_size_(0),
861 lists_size_(0),
862 count_(0),
863 present_flags_(0),
864 array_(NULL),
865 lists_(NULL),
866 free_list_head_(kNil) {
867 ResizeLists(kInitialSize);
868 Resize(kInitialSize);
869 }
870
871 void Kill(int flags);
872
873 void Add(HValue* value) {
874 present_flags_ |= value->flags();
875 Insert(value);
876 }
877
878 HValue* Lookup(HValue* value) const;
879 HValueMap* Copy() const { return new HValueMap(this); }
880
881 private:
882 // A linked list of HValue* values. Stored in arrays.
883 struct HValueMapListElement {
884 HValue* value;
885 int next; // Index in the array of the next list element.
886 };
887 static const int kNil = -1; // The end of a linked list
888
889 // Must be a power of 2.
890 static const int kInitialSize = 16;
891
892 explicit HValueMap(const HValueMap* other);
893
894 void Resize(int new_size);
895 void ResizeLists(int new_size);
896 void Insert(HValue* value);
897 uint32_t Bound(uint32_t value) const { return value & (array_size_ - 1); }
898
899 int array_size_;
900 int lists_size_;
901 int count_; // The number of values stored in the HValueMap.
902 int present_flags_; // All flags that are in any value in the HValueMap.
903 HValueMapListElement* array_; // Primary store - contains the first value
904 // with a given hash. Colliding elements are stored in linked lists.
905 HValueMapListElement* lists_; // The linked lists containing hash collisions.
906 int free_list_head_; // Unused elements in lists_ are on the free list.
907 };
908
909
910 class HStatistics: public Malloced {
911 public:
912 void Print();
913 void SaveTiming(const char* name, int64_t ticks);
914 static HStatistics* Instance() {
915 static SetOncePointer<HStatistics> instance;
916 if (!instance.is_set()) {
917 instance.set(new HStatistics());
918 }
919 return instance.get();
920 }
921
922 private:
923
924 HStatistics() : timing_(5), names_(5), total_(0), full_code_gen_(0) { }
925
926 List<int64_t> timing_;
927 List<const char*> names_;
928 int64_t total_;
929 int64_t full_code_gen_;
930 };
931
932
933 class HPhase BASE_EMBEDDED {
934 public:
935 static const char* const kFullCodeGen;
936 static const char* const kTotal;
937
938 explicit HPhase(const char* name) { Begin(name, NULL, NULL, NULL); }
939 HPhase(const char* name, HGraph* graph) {
940 Begin(name, graph, NULL, NULL);
941 }
942 HPhase(const char* name, LChunk* chunk) {
943 Begin(name, NULL, chunk, NULL);
944 }
945 HPhase(const char* name, LAllocator* allocator) {
946 Begin(name, NULL, NULL, allocator);
947 }
948
949 ~HPhase() {
950 End();
951 }
952
953 private:
954 void Begin(const char* name,
955 HGraph* graph,
956 LChunk* chunk,
957 LAllocator* allocator);
958 void End() const;
959
960 int64_t start_;
961 const char* name_;
962 HGraph* graph_;
963 LChunk* chunk_;
964 LAllocator* allocator_;
965 };
966
967
968 class HTracer: public Malloced {
969 public:
970 void TraceCompilation(FunctionLiteral* function);
971 void TraceHydrogen(const char* name, HGraph* graph);
972 void TraceLithium(const char* name, LChunk* chunk);
973 void TraceLiveRanges(const char* name, LAllocator* allocator);
974
975 static HTracer* Instance() {
976 static SetOncePointer<HTracer> instance;
977 if (!instance.is_set()) {
978 instance.set(new HTracer("hydrogen.cfg"));
979 }
980 return instance.get();
981 }
982
983 private:
984 class Tag BASE_EMBEDDED {
985 public:
986 Tag(HTracer* tracer, const char* name) {
987 name_ = name;
988 tracer_ = tracer;
989 tracer->PrintIndent();
990 tracer->trace_.Add("begin_%s\n", name);
991 tracer->indent_++;
992 }
993
994 ~Tag() {
995 tracer_->indent_--;
996 tracer_->PrintIndent();
997 tracer_->trace_.Add("end_%s\n", name_);
998 ASSERT(tracer_->indent_ >= 0);
999 tracer_->FlushToFile();
1000 }
1001
1002 private:
1003 HTracer* tracer_;
1004 const char* name_;
1005 };
1006
1007 explicit HTracer(const char* filename)
1008 : filename_(filename), trace_(&string_allocator_), indent_(0) {
1009 WriteChars(filename, "", 0, false);
1010 }
1011
1012 void TraceLiveRange(LiveRange* range, const char* type);
1013 void Trace(const char* name, HGraph* graph, LChunk* chunk);
1014 void FlushToFile();
1015
1016 void PrintEmptyProperty(const char* name) {
1017 PrintIndent();
1018 trace_.Add("%s\n", name);
1019 }
1020
1021 void PrintStringProperty(const char* name, const char* value) {
1022 PrintIndent();
1023 trace_.Add("%s \"%s\"\n", name, value);
1024 }
1025
1026 void PrintLongProperty(const char* name, int64_t value) {
1027 PrintIndent();
1028 trace_.Add("%s %d000\n", name, static_cast<int>(value / 1000));
1029 }
1030
1031 void PrintBlockProperty(const char* name, int block_id) {
1032 PrintIndent();
1033 trace_.Add("%s \"B%d\"\n", name, block_id);
1034 }
1035
1036 void PrintBlockProperty(const char* name, int block_id1, int block_id2) {
1037 PrintIndent();
1038 trace_.Add("%s \"B%d\" \"B%d\"\n", name, block_id1, block_id2);
1039 }
1040
1041 void PrintIntProperty(const char* name, int value) {
1042 PrintIndent();
1043 trace_.Add("%s %d\n", name, value);
1044 }
1045
1046 void PrintIndent() {
1047 for (int i = 0; i < indent_; i++) {
1048 trace_.Add(" ");
1049 }
1050 }
1051
1052 const char* filename_;
1053 HeapStringAllocator string_allocator_;
1054 StringStream trace_;
1055 int indent_;
1056 };
1057
1058
1059 } } // namespace v8::internal
1060
1061 #endif // V8_HYDROGEN_H_
OLDNEW
« no previous file with comments | « src/heap-inl.h ('k') | src/hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698