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

Side by Side Diff: runtime/vm/flow_graph_builder_test.cc

Issue 1566163003: Start testing source positions in flow graph (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 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 | « no previous file | runtime/vm/vm_sources.gypi » ('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 (c) 2016, the Dart project authors. Please see the AUTHORS file
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.
4
5 #include "vm/compiler.h"
6 #include "vm/dart_api_impl.h"
7 #include "vm/dart_entry.h"
8 #include "vm/flow_graph_builder.h"
9 #include "vm/intermediate_language.h"
10 #include "vm/unit_test.h"
11
12 namespace dart {
13
14 #define DUMP_EXPECT(condition) \
15 if (!(condition)) { \
16 dart::Expect(__FILE__, __LINE__).Fail("expected: %s", #condition); \
17 THR_Print(">>> BEGIN source position table for `%s`\n", graph_name_); \
18 Dump(); \
19 THR_Print("<<< END source position table for `%s`\n", graph_name_); \
20 }
21
22 class SourcePositionTest : public ValueObject {
23 public:
24 SourcePositionTest(Thread* thread,
25 const char* script)
26 : thread_(thread),
27 isolate_(thread->isolate()),
28 script_(script),
29 root_lib_(Library::Handle()),
30 root_script_(Script::Handle()),
31 graph_(NULL),
32 blocks_(NULL) {
33 EXPECT(thread_ != NULL);
34 EXPECT(isolate_ != NULL);
35 EXPECT(script_ != NULL);
36 Dart_Handle lib = TestCase::LoadTestScript(script, NULL);
37 EXPECT_VALID(lib);
38 root_lib_ ^= Api::UnwrapHandle(lib);
39 EXPECT(!root_lib_.IsNull());
40 root_script_ ^= root_lib_.LookupScript(
41 String::Handle(String::New(USER_TEST_URI)));
42 EXPECT(!root_script_.IsNull());
43 }
44
45 void BuildGraphFor(const char* function_name) {
46 graph_ = NULL;
47 blocks_ = NULL;
48 graph_name_ = NULL;
49
50 // Only support unoptimized code for now.
51 const bool optimized = false;
52
53 const Function& function =
54 Function::Handle(GetFunction(root_lib_, function_name));
55 ZoneGrowableArray<const ICData*>* ic_data_array =
56 new ZoneGrowableArray<const ICData*>();
57 ParsedFunction* parsed_function = new ParsedFunction(
58 thread_, Function::ZoneHandle(function.raw()));
59 Parser::ParseFunction(parsed_function);
60 parsed_function->AllocateVariables();
61 FlowGraphBuilder builder(
62 *parsed_function,
63 *ic_data_array,
64 NULL,
65 Compiler::kNoOSRDeoptId);
66 graph_ = builder.BuildGraph();
67 EXPECT(graph_ != NULL);
68 blocks_ = graph_->CodegenBlockOrder(optimized);
69 EXPECT(blocks_ != NULL);
70 graph_name_ = function_name;
71 EXPECT(graph_name_ != NULL);
72 }
73
74 // Expect to find an instance call at |line| and |column|.
75 void InstanceCallAt(intptr_t line,
76 intptr_t column = -1,
77 Token::Kind kind = Token::kNumTokens) {
78 Instruction* instr = FindFirstInstructionAt(line, column);
79 DUMP_EXPECT(instr->IsInstanceCall());
80 if (kind != Token::kNumTokens) {
81 DUMP_EXPECT(instr->AsInstanceCall()->token_kind() == kind);
82 }
83 }
84
85 // Expect that at least one of the instructions found at |line| and |column|
86 // contain |needle| in their |ToCString| representation.
87 void FuzzyInstructionMatchAt(const char* needle,
88 intptr_t line,
89 intptr_t column = -1) {
90 ZoneGrowableArray<Instruction*>* instructions =
91 FindInstructionsAt(line, column);
92 DUMP_EXPECT(instructions->length() > 0);
93 intptr_t count = 0;
94 for (intptr_t i = 0; i < instructions->length(); i++) {
95 Instruction* instr = instructions->At(i);
96 const char* haystack = instr->ToCString();
97 if (strstr(haystack, needle) != NULL) {
98 count++;
99 }
100 }
101 DUMP_EXPECT(count > 0);
102 }
103
104 // Utility to dump the instructions with token positions or line numbers.
105 void Dump() {
106 for (intptr_t i = 0; i < blocks_->length(); i++) {
107 BlockEntryInstr* entry = (*blocks_)[i];
108 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
109 Instruction* instr = it.Current();
110 const intptr_t token_pos = instr->token_pos();
111 if (token_pos < 0) {
112 THR_Print("%5d -- %s\n",
113 static_cast<int>(token_pos), instr->ToCString());
114 continue;
115 }
116 intptr_t token_line = -1;
117 intptr_t token_column = -1;
118 root_script_.GetTokenLocation(token_pos,
119 &token_line,
120 &token_column,
121 NULL);
122 THR_Print("%02d:%02d -- %s\n",
123 static_cast<int>(token_line),
124 static_cast<int>(token_column),
125 instr->ToCString());
126 }
127 }
128 }
129
130 private:
131 Instruction* FindFirstInstructionAt(intptr_t line, intptr_t column) {
132 ZoneGrowableArray<Instruction*>* instructions =
133 FindInstructionsAt(line, column);
134 DUMP_EXPECT(instructions->length() > 0);
135 return instructions->At(0);
136 }
137
138 ZoneGrowableArray<Instruction*>* FindInstructionsAt(
139 intptr_t line, intptr_t column) {
140 ZoneGrowableArray<Instruction*>* instructions =
141 new ZoneGrowableArray<Instruction*>();
142 for (intptr_t i = 0; i < blocks_->length(); i++) {
143 BlockEntryInstr* entry = (*blocks_)[i];
144 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
145 Instruction* instr = it.Current();
146 intptr_t token_pos = instr->token_pos();
147 if (token_pos < 0) {
148 continue;
149 }
150 intptr_t token_line = -1;
151 intptr_t token_column = -1;
152 root_script_.GetTokenLocation(token_pos,
153 &token_line,
154 &token_column,
155 NULL);
156 if (token_line == line) {
157 if ((column < 0) || (column == token_column)) {
158 instructions->Add(instr);
159 }
160 }
161 }
162 }
163 return instructions;
164 }
165
166 ZoneGrowableArray<Instruction*>* FindInstructionsAt(intptr_t token_pos) {
167 ZoneGrowableArray<Instruction*>* instructions =
168 new ZoneGrowableArray<Instruction*>();
169 for (intptr_t i = 0; i < blocks_->length(); i++) {
170 BlockEntryInstr* entry = (*blocks_)[i];
171 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
172 Instruction* instr = it.Current();
173 if (instr->token_pos() == token_pos) {
174 instructions->Add(instr);
175 }
176 }
177 }
178 return instructions;
179 }
180
181 RawFunction* GetFunction(const Library& lib, const char* name) {
182 const Function& result = Function::Handle(lib.LookupFunctionAllowPrivate(
183 String::Handle(String::New(name))));
184 EXPECT(!result.IsNull());
185 return result.raw();
186 }
187
188 RawFunction* GetFunction(const Class& cls, const char* name) {
189 const Function& result = Function::Handle(cls.LookupDynamicFunction(
rmacnak 2016/01/08 17:36:28 LookupFunctionAllowPrivate
Cutch 2016/01/08 19:03:28 Done.
190 String::Handle(String::New(name))));
191 EXPECT(!result.IsNull());
192 return result.raw();
193 }
194
195 RawClass* GetClass(const Library& lib, const char* name) {
196 const Class& cls = Class::Handle(
197 lib.LookupClass(String::Handle(Symbols::New(name))));
198 EXPECT(!cls.IsNull()); // No ambiguity error expected.
199 return cls.raw();
200 }
201
202 Thread* thread_;
203 Isolate* isolate_;
204 const char* script_;
205 Library& root_lib_;
206 Script& root_script_;
207 const char* graph_name_;
208 FlowGraph* graph_;
209 GrowableArray<BlockEntryInstr*>* blocks_;
210 };
211
212
213 TEST_CASE(SourcePosition_InstanceCalls) {
214 const char* kScript =
215 "var x = 5;\n"
216 "var y = 5;\n"
217 "main() {\n"
218 " var z = x + y;\n"
219 " return z;\n"
220 "}\n";
221
222 SourcePositionTest spt(thread, kScript);
223 spt.BuildGraphFor("main");
224 spt.FuzzyInstructionMatchAt("DebugStepCheck", 3, 5);
225 spt.FuzzyInstructionMatchAt("CheckStackOverflow", 3, 5);
226 spt.InstanceCallAt(4, 13, Token::kADD);
227 spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 3);
228 spt.FuzzyInstructionMatchAt("Return", 5, 3);
229 }
230
231 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/vm_sources.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698