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

Side by Side Diff: runtime/vm/intermediate_language.h

Issue 10830109: Add type propagation phase in optimizing compiler (work in progress). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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
OLDNEW
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 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_
6 #define VM_INTERMEDIATE_LANGUAGE_H_ 6 #define VM_INTERMEDIATE_LANGUAGE_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/ast.h" 9 #include "vm/ast.h"
10 #include "vm/growable_array.h" 10 #include "vm/growable_array.h"
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 #define DECLARE_COMPUTATION_TYPE(ShortName, ClassName) k##ShortName, 187 #define DECLARE_COMPUTATION_TYPE(ShortName, ClassName) k##ShortName,
188 188
189 FOR_EACH_COMPUTATION(DECLARE_COMPUTATION_TYPE) 189 FOR_EACH_COMPUTATION(DECLARE_COMPUTATION_TYPE)
190 190
191 #undef DECLARE_COMPUTATION_TYPE 191 #undef DECLARE_COMPUTATION_TYPE
192 }; 192 };
193 193
194 virtual ComputationType computation_type() const = 0; 194 virtual ComputationType computation_type() const = 0;
195 195
196 // Declare predicate for each computation. 196 // Declare predicate for each computation.
197 #define DECLARE_PREDICATE(ShortName, ClassName) \ 197 #define DECLARE_PREDICATE(ShortName, ClassName) \
198 inline bool Is##ShortName() const; \ 198 inline bool Is##ShortName() const; \
199 inline ClassName* As##ShortName(); 199 inline ClassName* As##ShortName();
200 FOR_EACH_COMPUTATION(DECLARE_PREDICATE) 200 FOR_EACH_COMPUTATION(DECLARE_PREDICATE)
201 #undef DECLARE_PREDICATE 201 #undef DECLARE_PREDICATE
202 202
203 private: 203 private:
204 friend class Instruction; 204 friend class BranchInstr;
205 friend class ReturnInstr;
206 friend class ThrowInstr;
207 friend class ReThrowInstr;
srdjan 2012/08/01 15:07:36 This is all because of access to GetNextCiD and Ge
regis 2012/08/01 17:10:35 Done.
205 static intptr_t GetNextCid(Isolate* isolate) { 208 static intptr_t GetNextCid(Isolate* isolate) {
206 intptr_t tmp = isolate->computation_id(); 209 intptr_t tmp = isolate->computation_id();
207 isolate->set_computation_id(tmp + 1); 210 isolate->set_computation_id(tmp + 1);
208 return tmp; 211 return tmp;
209 } 212 }
210 static ICData* GetICDataForCid(intptr_t cid, Isolate* isolate) { 213 static ICData* GetICDataForCid(intptr_t cid, Isolate* isolate) {
211 if (isolate->ic_data_array() == Array::null()) { 214 if (isolate->ic_data_array() == Array::null()) {
212 return NULL; 215 return NULL;
213 } else { 216 } else {
214 const Array& array_handle = Array::Handle(isolate->ic_data_array()); 217 const Array& array_handle = Array::Handle(isolate->ic_data_array());
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 293
291 protected: 294 protected:
292 EmbeddedArray<Value*, N> inputs_; 295 EmbeddedArray<Value*, N> inputs_;
293 }; 296 };
294 297
295 298
296 class Value : public TemplateComputation<0> { 299 class Value : public TemplateComputation<0> {
297 public: 300 public:
298 Value() { } 301 Value() { }
299 302
303 bool StaticTypeIsMoreSpecificThan(const AbstractType& dst_type);
srdjan 2012/08/01 15:07:36 const ?
regis 2012/08/01 17:10:35 Done. But I needed to overload AsConstant with a c
304
300 private: 305 private:
301 DISALLOW_COPY_AND_ASSIGN(Value); 306 DISALLOW_COPY_AND_ASSIGN(Value);
302 }; 307 };
303 308
304 309
305 // Functions defined in all concrete computation classes. 310 // Functions defined in all concrete computation classes.
306 #define DECLARE_COMPUTATION(ShortName) \ 311 #define DECLARE_COMPUTATION(ShortName) \
307 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr); \ 312 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr); \
308 virtual ComputationType computation_type() const { \ 313 virtual ComputationType computation_type() const { \
309 return Computation::k##ShortName; \ 314 return Computation::k##ShortName; \
(...skipping 1407 matching lines...) Expand 10 before | Expand all | Expand 10 after
1717 virtual Value* InputAt(intptr_t i) const; \ 1722 virtual Value* InputAt(intptr_t i) const; \
1718 virtual void SetInputAt(intptr_t i, Value* value); \ 1723 virtual void SetInputAt(intptr_t i, Value* value); \
1719 virtual const char* DebugName() const { return #type; } \ 1724 virtual const char* DebugName() const { return #type; } \
1720 virtual void PrintTo(BufferFormatter* f) const; \ 1725 virtual void PrintTo(BufferFormatter* f) const; \
1721 virtual void PrintToVisualizer(BufferFormatter* f) const; 1726 virtual void PrintToVisualizer(BufferFormatter* f) const;
1722 1727
1723 1728
1724 class Instruction : public ZoneAllocated { 1729 class Instruction : public ZoneAllocated {
1725 public: 1730 public:
1726 Instruction() 1731 Instruction()
1727 : cid_(-1), 1732 : lifetime_position_(-1), previous_(NULL), next_(NULL), env_(NULL) { }
1728 lifetime_position_(-1),
1729 ic_data_(NULL),
1730 previous_(NULL),
1731 next_(NULL),
1732 env_(NULL) {
1733 Isolate* isolate = Isolate::Current();
1734 cid_ = Computation::GetNextCid(isolate);
1735 ic_data_ = Computation::GetICDataForCid(cid_, isolate);
1736 }
1737
1738 // Unique computation/instruction id, used for deoptimization, e.g. for
1739 // ReturnInstr, ThrowInstr and ReThrowInstr.
1740 intptr_t cid() const { return cid_; }
1741
1742 const ICData* ic_data() const { return ic_data_; }
1743 bool HasICData() const {
1744 return (ic_data() != NULL) && !ic_data()->IsNull();
1745 }
1746 1733
1747 virtual bool IsBlockEntry() const { return false; } 1734 virtual bool IsBlockEntry() const { return false; }
1748 BlockEntryInstr* AsBlockEntry() { 1735 BlockEntryInstr* AsBlockEntry() {
1749 return IsBlockEntry() ? reinterpret_cast<BlockEntryInstr*>(this) : NULL; 1736 return IsBlockEntry() ? reinterpret_cast<BlockEntryInstr*>(this) : NULL;
1750 } 1737 }
1751 virtual bool IsDefinition() const { return false; } 1738 virtual bool IsDefinition() const { return false; }
1752 virtual Definition* AsDefinition() { return NULL; } 1739 virtual Definition* AsDefinition() { return NULL; }
1753 1740
1754 virtual intptr_t InputCount() const = 0; 1741 virtual intptr_t InputCount() const = 0;
1755 virtual Value* InputAt(intptr_t i) const = 0; 1742 virtual Value* InputAt(intptr_t i) const = 0;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1848 1835
1849 Environment* env() const { return env_; } 1836 Environment* env() const { return env_; }
1850 void set_env(Environment* env) { env_ = env; } 1837 void set_env(Environment* env) { env_ = env; }
1851 1838
1852 intptr_t lifetime_position() const { return lifetime_position_; } 1839 intptr_t lifetime_position() const { return lifetime_position_; }
1853 void set_lifetime_position(intptr_t pos) { 1840 void set_lifetime_position(intptr_t pos) {
1854 lifetime_position_ = pos; 1841 lifetime_position_ = pos;
1855 } 1842 }
1856 1843
1857 private: 1844 private:
1858 intptr_t cid_; // Computation id.
1859 intptr_t lifetime_position_; // Position used by register allocator. 1845 intptr_t lifetime_position_; // Position used by register allocator.
1860 ICData* ic_data_;
1861 Instruction* previous_; 1846 Instruction* previous_;
1862 Instruction* next_; 1847 Instruction* next_;
1863 Environment* env_; 1848 Environment* env_;
1864 DISALLOW_COPY_AND_ASSIGN(Instruction); 1849 DISALLOW_COPY_AND_ASSIGN(Instruction);
1865 }; 1850 };
1866 1851
1867 1852
1868 class InstructionWithInputs : public Instruction { 1853 class InstructionWithInputs : public Instruction {
1869 public: 1854 public:
1870 InstructionWithInputs() : locs_(NULL) { } 1855 InstructionWithInputs() : locs_(NULL) { }
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
2391 private: 2376 private:
2392 Value* value_; 2377 Value* value_;
2393 2378
2394 DISALLOW_COPY_AND_ASSIGN(PushArgumentInstr); 2379 DISALLOW_COPY_AND_ASSIGN(PushArgumentInstr);
2395 }; 2380 };
2396 2381
2397 2382
2398 class ReturnInstr : public InstructionWithInputs { 2383 class ReturnInstr : public InstructionWithInputs {
2399 public: 2384 public:
2400 ReturnInstr(intptr_t token_pos, Value* value) 2385 ReturnInstr(intptr_t token_pos, Value* value)
2401 : InstructionWithInputs(), token_pos_(token_pos), value_(value) { 2386 : InstructionWithInputs(),
2387 cid_(-1),
srdjan 2012/08/01 15:07:36 make cid_ const and initialize it here.
regis 2012/08/01 17:10:35 Done.
2388 token_pos_(token_pos),
2389 value_(value) {
2402 ASSERT(value_ != NULL); 2390 ASSERT(value_ != NULL);
2391 Isolate* isolate = Isolate::Current();
2392 cid_ = Computation::GetNextCid(isolate);
2403 } 2393 }
2404 2394
2405 DECLARE_INSTRUCTION(Return) 2395 DECLARE_INSTRUCTION(Return)
2406 2396
2397 intptr_t cid() const { return cid_; }
2398 intptr_t token_pos() const { return token_pos_; }
2407 Value* value() const { return value_; } 2399 Value* value() const { return value_; }
2408 intptr_t token_pos() const { return token_pos_; }
2409 2400
2410 virtual LocationSummary* MakeLocationSummary() const; 2401 virtual LocationSummary* MakeLocationSummary() const;
2411 2402
2412 virtual void EmitNativeCode(FlowGraphCompiler* compiler); 2403 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
2413 2404
2414 private: 2405 private:
2406 intptr_t cid_; // Computation/instruction id.
2415 const intptr_t token_pos_; 2407 const intptr_t token_pos_;
2416 Value* value_; 2408 Value* value_;
2417 2409
2418 DISALLOW_COPY_AND_ASSIGN(ReturnInstr); 2410 DISALLOW_COPY_AND_ASSIGN(ReturnInstr);
2419 }; 2411 };
2420 2412
2421 2413
2422 class ThrowInstr : public InstructionWithInputs { 2414 class ThrowInstr : public InstructionWithInputs {
2423 public: 2415 public:
2424 ThrowInstr(intptr_t token_pos, 2416 ThrowInstr(intptr_t token_pos,
2425 intptr_t try_index, 2417 intptr_t try_index,
2426 Value* exception) 2418 Value* exception)
2427 : InstructionWithInputs(), 2419 : InstructionWithInputs(),
2420 cid_(-1),
srdjan 2012/08/01 15:07:36 ditto
regis 2012/08/01 17:10:35 Done.
2428 token_pos_(token_pos), 2421 token_pos_(token_pos),
2429 try_index_(try_index), 2422 try_index_(try_index),
2430 exception_(exception) { 2423 exception_(exception) {
2431 ASSERT(exception_ != NULL); 2424 ASSERT(exception_ != NULL);
2425 Isolate* isolate = Isolate::Current();
2426 cid_ = Computation::GetNextCid(isolate);
2432 } 2427 }
2433 2428
2434 DECLARE_INSTRUCTION(Throw) 2429 DECLARE_INSTRUCTION(Throw)
2435 2430
2431 intptr_t cid() const { return cid_; }
2436 intptr_t token_pos() const { return token_pos_; } 2432 intptr_t token_pos() const { return token_pos_; }
2437 intptr_t try_index() const { return try_index_; } 2433 intptr_t try_index() const { return try_index_; }
2438 Value* exception() const { return exception_; } 2434 Value* exception() const { return exception_; }
2439 2435
2440 virtual LocationSummary* MakeLocationSummary() const; 2436 virtual LocationSummary* MakeLocationSummary() const;
2441 2437
2442 virtual void EmitNativeCode(FlowGraphCompiler* compiler); 2438 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
2443 2439
2444 private: 2440 private:
2441 intptr_t cid_; // Computation/instruction id.
2445 const intptr_t token_pos_; 2442 const intptr_t token_pos_;
2446 const intptr_t try_index_; 2443 const intptr_t try_index_;
2447 Value* exception_; 2444 Value* exception_;
2448 2445
2449 DISALLOW_COPY_AND_ASSIGN(ThrowInstr); 2446 DISALLOW_COPY_AND_ASSIGN(ThrowInstr);
2450 }; 2447 };
2451 2448
2452 2449
2453 class ReThrowInstr : public InstructionWithInputs { 2450 class ReThrowInstr : public InstructionWithInputs {
2454 public: 2451 public:
2455 ReThrowInstr(intptr_t token_pos, 2452 ReThrowInstr(intptr_t token_pos,
2456 intptr_t try_index, 2453 intptr_t try_index,
2457 Value* exception, 2454 Value* exception,
2458 Value* stack_trace) 2455 Value* stack_trace)
2459 : InstructionWithInputs(), 2456 : InstructionWithInputs(),
2457 cid_(-1),
srdjan 2012/08/01 15:07:36 ditto
regis 2012/08/01 17:10:35 Done.
2460 token_pos_(token_pos), 2458 token_pos_(token_pos),
2461 try_index_(try_index), 2459 try_index_(try_index),
2462 exception_(exception), 2460 exception_(exception),
2463 stack_trace_(stack_trace) { 2461 stack_trace_(stack_trace) {
2464 ASSERT(exception_ != NULL); 2462 ASSERT(exception_ != NULL);
2465 ASSERT(stack_trace_ != NULL); 2463 ASSERT(stack_trace_ != NULL);
2464 Isolate* isolate = Isolate::Current();
2465 cid_ = Computation::GetNextCid(isolate);
2466 } 2466 }
2467 2467
2468 DECLARE_INSTRUCTION(ReThrow) 2468 DECLARE_INSTRUCTION(ReThrow)
2469 2469
2470 intptr_t cid() const { return cid_; }
2470 intptr_t token_pos() const { return token_pos_; } 2471 intptr_t token_pos() const { return token_pos_; }
2471 intptr_t try_index() const { return try_index_; } 2472 intptr_t try_index() const { return try_index_; }
2472 Value* exception() const { return exception_; } 2473 Value* exception() const { return exception_; }
2473 Value* stack_trace() const { return stack_trace_; } 2474 Value* stack_trace() const { return stack_trace_; }
2474 2475
2475 virtual LocationSummary* MakeLocationSummary() const; 2476 virtual LocationSummary* MakeLocationSummary() const;
2476 2477
2477 virtual void EmitNativeCode(FlowGraphCompiler* compiler); 2478 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
2478 2479
2479 private: 2480 private:
2481 intptr_t cid_; // Computation/instruction id.
2480 const intptr_t token_pos_; 2482 const intptr_t token_pos_;
2481 const intptr_t try_index_; 2483 const intptr_t try_index_;
2482 Value* exception_; 2484 Value* exception_;
2483 Value* stack_trace_; 2485 Value* stack_trace_;
2484 2486
2485 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); 2487 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr);
2486 }; 2488 };
2487 2489
2488 2490
2489 class GotoInstr : public InstructionWithInputs { 2491 class GotoInstr : public InstructionWithInputs {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2525 // Parallel move that will be used by linear scan register allocator to 2527 // Parallel move that will be used by linear scan register allocator to
2526 // connect live ranges at the end of the block and resolve phis. 2528 // connect live ranges at the end of the block and resolve phis.
2527 ParallelMoveInstr* parallel_move_; 2529 ParallelMoveInstr* parallel_move_;
2528 }; 2530 };
2529 2531
2530 2532
2531 class BranchInstr : public InstructionWithInputs { 2533 class BranchInstr : public InstructionWithInputs {
2532 public: 2534 public:
2533 BranchInstr(intptr_t token_pos, 2535 BranchInstr(intptr_t token_pos,
2534 intptr_t try_index, 2536 intptr_t try_index,
2535 Value* left, 2537 Value* left,
2536 Value* right, 2538 Value* right,
2537 Token::Kind kind) 2539 Token::Kind kind)
2538 : InstructionWithInputs(), 2540 : InstructionWithInputs(),
2541 cid_(-1),
2542 ic_data_(NULL),
2539 token_pos_(token_pos), 2543 token_pos_(token_pos),
2540 try_index_(try_index), 2544 try_index_(try_index),
2541 left_(left), 2545 left_(left),
2542 right_(right), 2546 right_(right),
2543 kind_(kind), 2547 kind_(kind),
2544 true_successor_(NULL), 2548 true_successor_(NULL),
2545 false_successor_(NULL) { 2549 false_successor_(NULL) {
2546 ASSERT(left_ != NULL); 2550 ASSERT(left_ != NULL);
2547 ASSERT(right_ != NULL); 2551 ASSERT(right_ != NULL);
2548 ASSERT(Token::IsEqualityOperator(kind) || 2552 ASSERT(Token::IsEqualityOperator(kind) ||
2549 Token::IsRelationalOperator(kind) || 2553 Token::IsRelationalOperator(kind) ||
2550 Token::IsTypeTestOperator(kind)); 2554 Token::IsTypeTestOperator(kind));
2555 Isolate* isolate = Isolate::Current();
2556 cid_ = Computation::GetNextCid(isolate);
2557 ic_data_ = Computation::GetICDataForCid(cid_, isolate);
2551 } 2558 }
2552 2559
2553 DECLARE_INSTRUCTION(Branch) 2560 DECLARE_INSTRUCTION(Branch)
2554 2561
2555 Value* left() const { return left_; } 2562 Value* left() const { return left_; }
2556 Value* right() const { return right_; } 2563 Value* right() const { return right_; }
2557 Token::Kind kind() const { return kind_; } 2564 Token::Kind kind() const { return kind_; }
2558 void set_kind(Token::Kind kind) { 2565 void set_kind(Token::Kind kind) {
2559 ASSERT(Token::IsEqualityOperator(kind) || 2566 ASSERT(Token::IsEqualityOperator(kind) ||
2560 Token::IsRelationalOperator(kind) || 2567 Token::IsRelationalOperator(kind) ||
2561 Token::IsTypeTestOperator(kind)); 2568 Token::IsTypeTestOperator(kind));
2562 kind_ = kind; 2569 kind_ = kind;
2563 } 2570 }
2571
2572 intptr_t cid() const { return cid_; }
2573
2574 const ICData* ic_data() const { return ic_data_; }
2575 bool HasICData() const {
2576 return (ic_data() != NULL) && !ic_data()->IsNull();
2577 }
2578
2564 intptr_t token_pos() const { return token_pos_;} 2579 intptr_t token_pos() const { return token_pos_;}
2565 intptr_t try_index() const { return try_index_; } 2580 intptr_t try_index() const { return try_index_; }
2566 2581
2567 TargetEntryInstr* true_successor() const { return true_successor_; } 2582 TargetEntryInstr* true_successor() const { return true_successor_; }
2568 TargetEntryInstr* false_successor() const { return false_successor_; } 2583 TargetEntryInstr* false_successor() const { return false_successor_; }
2569 2584
2570 TargetEntryInstr** true_successor_address() { return &true_successor_; } 2585 TargetEntryInstr** true_successor_address() { return &true_successor_; }
2571 TargetEntryInstr** false_successor_address() { return &false_successor_; } 2586 TargetEntryInstr** false_successor_address() { return &false_successor_; }
2572 2587
2573 virtual intptr_t SuccessorCount() const; 2588 virtual intptr_t SuccessorCount() const;
2574 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 2589 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
2575 2590
2576 virtual void DiscoverBlocks( 2591 virtual void DiscoverBlocks(
2577 BlockEntryInstr* current_block, 2592 BlockEntryInstr* current_block,
2578 GrowableArray<BlockEntryInstr*>* preorder, 2593 GrowableArray<BlockEntryInstr*>* preorder,
2579 GrowableArray<BlockEntryInstr*>* postorder, 2594 GrowableArray<BlockEntryInstr*>* postorder,
2580 GrowableArray<intptr_t>* parent, 2595 GrowableArray<intptr_t>* parent,
2581 GrowableArray<BitVector*>* assigned_vars, 2596 GrowableArray<BitVector*>* assigned_vars,
2582 intptr_t variable_count, 2597 intptr_t variable_count,
2583 intptr_t fixed_parameter_count); 2598 intptr_t fixed_parameter_count);
2584 2599
2585 virtual LocationSummary* MakeLocationSummary() const; 2600 virtual LocationSummary* MakeLocationSummary() const;
2586 2601
2587 virtual void EmitNativeCode(FlowGraphCompiler* compiler); 2602 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
2588 2603
2589 void EmitBranchOnCondition(FlowGraphCompiler* compiler, 2604 void EmitBranchOnCondition(FlowGraphCompiler* compiler,
2590 Condition true_condition); 2605 Condition true_condition);
2591 2606
2592 private: 2607 private:
2608 intptr_t cid_; // Computation/instruction id.
2609 ICData* ic_data_;
2593 const intptr_t token_pos_; 2610 const intptr_t token_pos_;
2594 const intptr_t try_index_; 2611 const intptr_t try_index_;
2595 Value* left_; 2612 Value* left_;
2596 Value* right_; 2613 Value* right_;
2597 Token::Kind kind_; 2614 Token::Kind kind_;
2598 TargetEntryInstr* true_successor_; 2615 TargetEntryInstr* true_successor_;
2599 TargetEntryInstr* false_successor_; 2616 TargetEntryInstr* false_successor_;
2600 2617
2601 DISALLOW_COPY_AND_ASSIGN(BranchInstr); 2618 DISALLOW_COPY_AND_ASSIGN(BranchInstr);
2602 }; 2619 };
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
2680 const GrowableArray<BlockEntryInstr*>& block_order_; 2697 const GrowableArray<BlockEntryInstr*>& block_order_;
2681 2698
2682 private: 2699 private:
2683 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 2700 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
2684 }; 2701 };
2685 2702
2686 2703
2687 } // namespace dart 2704 } // namespace dart
2688 2705
2689 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 2706 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698