OLD | NEW |
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 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "lib/error.h" | 10 #include "lib/error.h" |
11 #include "vm/flow_graph_compiler.h" | 11 #include "vm/flow_graph_compiler.h" |
12 #include "vm/locations.h" | 12 #include "vm/locations.h" |
13 #include "vm/object_store.h" | 13 #include "vm/object_store.h" |
14 #include "vm/parser.h" | 14 #include "vm/parser.h" |
15 #include "vm/stub_code.h" | 15 #include "vm/stub_code.h" |
16 | 16 |
17 #define __ compiler->assembler()-> | 17 #define __ compiler->assembler()-> |
18 | 18 |
19 namespace dart { | 19 namespace dart { |
20 | 20 |
21 DECLARE_FLAG(int, optimization_counter_threshold); | 21 DECLARE_FLAG(int, optimization_counter_threshold); |
22 DECLARE_FLAG(bool, trace_functions); | 22 DECLARE_FLAG(bool, trace_functions); |
23 | 23 |
24 | 24 |
25 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 25 void BindInstr::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
26 computation()->EmitNativeCode(compiler); | 26 computation()->EmitNativeCode(compiler); |
27 __ pushq(locs()->out().reg()); | 27 __ pushq(locs()->out().reg()); |
28 } | 28 } |
29 | 29 |
30 | 30 |
31 LocationSummary* ReturnInstr::MakeLocationSummary() const { | 31 LocationSummary* ReturnInstr::MakeLocationSummary() const { |
32 const intptr_t kNumInputs = 1; | 32 const intptr_t kNumInputs = 1; |
33 const intptr_t kNumTemps = 1; | 33 const intptr_t kNumTemps = 1; |
34 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 34 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
35 locs->set_in(0, Location::RegisterLocation(RAX)); | 35 locs->set_in(0, Location::RegisterLocation(RAX)); |
36 locs->set_temp(0, Location::RequiresRegister()); | 36 locs->set_temp(0, Location::RequiresRegister()); |
37 return locs; | 37 return locs; |
38 } | 38 } |
39 | 39 |
40 | 40 |
41 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 41 void ReturnInstr::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
42 Register result = locs()->in(0).reg(); | 42 Register result = locs()->in(0).reg(); |
43 Register temp = locs()->temp(0).reg(); | 43 Register temp = locs()->temp(0).reg(); |
44 ASSERT(result == RAX); | 44 ASSERT(result == RAX); |
45 if (!compiler->is_optimizing()) { | 45 if (!compiler->is_optimizing()) { |
46 // Count only in unoptimized code. | 46 // Count only in unoptimized code. |
47 // TODO(srdjan): Replace the counting code with a type feedback | 47 // TODO(srdjan): Replace the counting code with a type feedback |
48 // collection and counting stub. | 48 // collection and counting stub. |
49 const Function& function = | 49 const Function& function = |
50 Function::ZoneHandle(compiler->parsed_function().function().raw()); | 50 Function::ZoneHandle(compiler->parsed_function().function().raw()); |
51 __ LoadObject(temp, function); | 51 __ LoadObject(temp, function); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. | 114 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. |
115 return result; | 115 return result; |
116 } | 116 } |
117 | 117 |
118 | 118 |
119 LocationSummary* LoadLocalComp::MakeLocationSummary() const { | 119 LocationSummary* LoadLocalComp::MakeLocationSummary() const { |
120 return LocationSummary::Make(0, Location::RequiresRegister()); | 120 return LocationSummary::Make(0, Location::RequiresRegister()); |
121 } | 121 } |
122 | 122 |
123 | 123 |
124 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 124 void LoadLocalComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
125 Register result = locs()->out().reg(); | 125 Register result = locs()->out().reg(); |
126 __ movq(result, Address(RBP, local().index() * kWordSize)); | 126 __ movq(result, Address(RBP, local().index() * kWordSize)); |
127 } | 127 } |
128 | 128 |
129 | 129 |
130 LocationSummary* StoreLocalComp::MakeLocationSummary() const { | 130 LocationSummary* StoreLocalComp::MakeLocationSummary() const { |
131 return LocationSummary::Make(1, Location::SameAsFirstInput()); | 131 return LocationSummary::Make(1, Location::SameAsFirstInput()); |
132 } | 132 } |
133 | 133 |
134 | 134 |
135 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 135 void StoreLocalComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
136 Register value = locs()->in(0).reg(); | 136 Register value = locs()->in(0).reg(); |
137 Register result = locs()->out().reg(); | 137 Register result = locs()->out().reg(); |
138 ASSERT(result == value); // Assert that register assignment is correct. | 138 ASSERT(result == value); // Assert that register assignment is correct. |
139 __ movq(Address(RBP, local().index() * kWordSize), value); | 139 __ movq(Address(RBP, local().index() * kWordSize), value); |
140 } | 140 } |
141 | 141 |
142 | 142 |
143 LocationSummary* ConstantVal::MakeLocationSummary() const { | 143 LocationSummary* ConstantVal::MakeLocationSummary() const { |
144 return LocationSummary::Make(0, Location::RequiresRegister()); | 144 return LocationSummary::Make(0, Location::RequiresRegister()); |
145 } | 145 } |
146 | 146 |
147 | 147 |
148 void ConstantVal::EmitNativeCode(FlowGraphCompiler* compiler) { | 148 void ConstantVal::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
149 Register result = locs()->out().reg(); | 149 Register result = locs()->out().reg(); |
150 if (value().IsSmi()) { | 150 if (value().IsSmi()) { |
151 int64_t imm = reinterpret_cast<int64_t>(value().raw()); | 151 int64_t imm = reinterpret_cast<int64_t>(value().raw()); |
152 __ movq(result, Immediate(imm)); | 152 __ movq(result, Immediate(imm)); |
153 } else { | 153 } else { |
154 __ LoadObject(result, value()); | 154 __ LoadObject(result, value()); |
155 } | 155 } |
156 } | 156 } |
157 | 157 |
158 | 158 |
159 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { | 159 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { |
160 LocationSummary* summary = new LocationSummary(3, 0); | 160 LocationSummary* summary = new LocationSummary(3, 0); |
161 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. | 161 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. |
162 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. | 162 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. |
163 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments. | 163 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments. |
164 summary->set_out(Location::RegisterLocation(RAX)); | 164 summary->set_out(Location::RegisterLocation(RAX)); |
165 return summary; | 165 return summary; |
166 } | 166 } |
167 | 167 |
168 | 168 |
169 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 169 void AssertBooleanComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
170 Register obj = locs()->in(0).reg(); | 170 Register obj = locs()->in(0).reg(); |
171 Register result = locs()->out().reg(); | 171 Register result = locs()->out().reg(); |
172 | 172 |
173 // Check that the type of the value is allowed in conditional context. | 173 // Check that the type of the value is allowed in conditional context. |
174 // Call the runtime if the object is not bool::true or bool::false. | 174 // Call the runtime if the object is not bool::true or bool::false. |
175 Label done; | 175 Label done; |
176 __ CompareObject(obj, Bool::ZoneHandle(Bool::True())); | 176 __ CompareObject(obj, Bool::ZoneHandle(Bool::True())); |
177 __ j(EQUAL, &done, Assembler::kNearJump); | 177 __ j(EQUAL, &done, Assembler::kNearJump); |
178 __ CompareObject(obj, Bool::ZoneHandle(Bool::False())); | 178 __ CompareObject(obj, Bool::ZoneHandle(Bool::False())); |
179 __ j(EQUAL, &done, Assembler::kNearJump); | 179 __ j(EQUAL, &done, Assembler::kNearJump); |
(...skipping 14 matching lines...) Expand all Loading... |
194 | 194 |
195 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { | 195 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { |
196 LocationSummary* locs = new LocationSummary(2, 0); | 196 LocationSummary* locs = new LocationSummary(2, 0); |
197 locs->set_in(0, Location::RequiresRegister()); | 197 locs->set_in(0, Location::RequiresRegister()); |
198 locs->set_in(1, Location::RequiresRegister()); | 198 locs->set_in(1, Location::RequiresRegister()); |
199 locs->set_out(Location::RegisterLocation(RAX)); | 199 locs->set_out(Location::RegisterLocation(RAX)); |
200 return locs; | 200 return locs; |
201 } | 201 } |
202 | 202 |
203 | 203 |
204 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 204 void EqualityCompareComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
205 Register left = locs()->in(0).reg(); | 205 Register left = locs()->in(0).reg(); |
206 Register right = locs()->in(1).reg(); | 206 Register right = locs()->in(1).reg(); |
207 Register result = locs()->out().reg(); | 207 Register result = locs()->out().reg(); |
208 ASSERT(locs()->out().reg() == RAX); | 208 ASSERT(locs()->out().reg() == RAX); |
209 | 209 |
210 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 210 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
211 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 211 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
212 const Immediate raw_null = | 212 const Immediate raw_null = |
213 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 213 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
214 Label done, load_true, non_null_compare; | 214 Label done, load_true, non_null_compare; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 LocationSummary* NativeCallComp::MakeLocationSummary() const { | 246 LocationSummary* NativeCallComp::MakeLocationSummary() const { |
247 LocationSummary* locs = new LocationSummary(0, 3); | 247 LocationSummary* locs = new LocationSummary(0, 3); |
248 locs->set_temp(0, Location::RegisterLocation(RAX)); | 248 locs->set_temp(0, Location::RegisterLocation(RAX)); |
249 locs->set_temp(1, Location::RegisterLocation(RBX)); | 249 locs->set_temp(1, Location::RegisterLocation(RBX)); |
250 locs->set_temp(2, Location::RegisterLocation(R10)); | 250 locs->set_temp(2, Location::RegisterLocation(R10)); |
251 locs->set_out(Location::RequiresRegister()); | 251 locs->set_out(Location::RequiresRegister()); |
252 return locs; | 252 return locs; |
253 } | 253 } |
254 | 254 |
255 | 255 |
256 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 256 void NativeCallComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
257 ASSERT(locs()->temp(0).reg() == RAX); | 257 ASSERT(locs()->temp(0).reg() == RAX); |
258 ASSERT(locs()->temp(1).reg() == RBX); | 258 ASSERT(locs()->temp(1).reg() == RBX); |
259 ASSERT(locs()->temp(2).reg() == R10); | 259 ASSERT(locs()->temp(2).reg() == R10); |
260 Register result = locs()->out().reg(); | 260 Register result = locs()->out().reg(); |
261 | 261 |
262 // Push the result place holder initialized to NULL. | 262 // Push the result place holder initialized to NULL. |
263 __ PushObject(Object::ZoneHandle()); | 263 __ PushObject(Object::ZoneHandle()); |
264 // Pass a pointer to the first argument in RAX. | 264 // Pass a pointer to the first argument in RAX. |
265 if (!has_optional_parameters()) { | 265 if (!has_optional_parameters()) { |
266 __ leaq(RAX, Address(RBP, (1 + argument_count()) * kWordSize)); | 266 __ leaq(RAX, Address(RBP, (1 + argument_count()) * kWordSize)); |
(...skipping 10 matching lines...) Expand all Loading... |
277 __ popq(result); | 277 __ popq(result); |
278 } | 278 } |
279 | 279 |
280 | 280 |
281 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { | 281 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { |
282 const intptr_t kNumInputs = 3; | 282 const intptr_t kNumInputs = 3; |
283 return LocationSummary::Make(kNumInputs, Location::NoLocation()); | 283 return LocationSummary::Make(kNumInputs, Location::NoLocation()); |
284 } | 284 } |
285 | 285 |
286 | 286 |
287 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 287 void StoreIndexedComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
288 Register receiver = locs()->in(0).reg(); | 288 Register receiver = locs()->in(0).reg(); |
289 Register index = locs()->in(1).reg(); | 289 Register index = locs()->in(1).reg(); |
290 Register value = locs()->in(2).reg(); | 290 Register value = locs()->in(2).reg(); |
291 | 291 |
292 const String& function_name = | 292 const String& function_name = |
293 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); | 293 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); |
294 | 294 |
295 __ pushq(receiver); | 295 __ pushq(receiver); |
296 __ pushq(index); | 296 __ pushq(index); |
297 __ pushq(value); | 297 __ pushq(value); |
298 const intptr_t kNumArguments = 3; | 298 const intptr_t kNumArguments = 3; |
299 const intptr_t kNumArgsChecked = 1; // Type-feedback. | 299 const intptr_t kNumArgsChecked = 1; // Type-feedback. |
300 compiler->GenerateInstanceCall(cid(), | 300 compiler->GenerateInstanceCall(cid(), |
301 token_index(), | 301 token_index(), |
302 try_index(), | 302 try_index(), |
303 function_name, | 303 function_name, |
304 kNumArguments, | 304 kNumArguments, |
305 Array::ZoneHandle(), // No optional arguments. | 305 Array::ZoneHandle(), // No optional arguments. |
306 kNumArgsChecked); | 306 kNumArgsChecked); |
307 } | 307 } |
308 | 308 |
309 | 309 |
310 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { | 310 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { |
311 const intptr_t kNumInputs = 2; | 311 const intptr_t kNumInputs = 2; |
312 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); | 312 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); |
313 return NULL; | 313 return NULL; |
314 } | 314 } |
315 | 315 |
316 | 316 |
317 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 317 void InstanceSetterComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
318 Register receiver = locs()->in(0).reg(); | 318 Register receiver = locs()->in(0).reg(); |
319 Register value = locs()->in(1).reg(); | 319 Register value = locs()->in(1).reg(); |
320 Register result = locs()->out().reg(); | 320 Register result = locs()->out().reg(); |
321 | 321 |
322 // Preserve the value (second argument) under the arguments as the result | 322 // Preserve the value (second argument) under the arguments as the result |
323 // of the computation, then call the setter. | 323 // of the computation, then call the setter. |
324 const String& function_name = | 324 const String& function_name = |
325 String::ZoneHandle(Field::SetterSymbol(field_name())); | 325 String::ZoneHandle(Field::SetterSymbol(field_name())); |
326 | 326 |
327 // Insert a copy of the second (last) argument under the arguments. | 327 // Insert a copy of the second (last) argument under the arguments. |
(...skipping 13 matching lines...) Expand all Loading... |
341 __ popq(result); | 341 __ popq(result); |
342 } | 342 } |
343 | 343 |
344 | 344 |
345 LocationSummary* StaticSetterComp::MakeLocationSummary() const { | 345 LocationSummary* StaticSetterComp::MakeLocationSummary() const { |
346 const intptr_t kNumInputs = 1; | 346 const intptr_t kNumInputs = 1; |
347 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); | 347 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); |
348 } | 348 } |
349 | 349 |
350 | 350 |
351 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 351 void StaticSetterComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
352 Register value = locs()->in(0).reg(); | 352 Register value = locs()->in(0).reg(); |
353 Register result = locs()->out().reg(); | 353 Register result = locs()->out().reg(); |
354 | 354 |
355 // Preserve the argument as the result of the computation, | 355 // Preserve the argument as the result of the computation, |
356 // then call the setter. | 356 // then call the setter. |
357 | 357 |
358 // Duplicate the argument. | 358 // Duplicate the argument. |
359 // TODO(fschneider): Avoid preserving the value if the result is not used. | 359 // TODO(fschneider): Avoid preserving the value if the result is not used. |
360 __ pushq(value); | 360 __ pushq(value); |
361 __ pushq(value); | 361 __ pushq(value); |
362 compiler->GenerateStaticCall(cid(), | 362 compiler->GenerateStaticCall(cid(), |
363 token_index(), | 363 token_index(), |
364 try_index(), | 364 try_index(), |
365 setter_function(), | 365 setter_function(), |
366 1, | 366 1, |
367 Array::ZoneHandle()); | 367 Array::ZoneHandle()); |
368 __ popq(result); | 368 __ popq(result); |
369 } | 369 } |
370 | 370 |
371 | 371 |
372 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { | 372 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { |
373 // TODO(fschneider): For this instruction the input register may be | 373 // TODO(fschneider): For this instruction the input register may be |
374 // reused for the result (but is not required to) because the input | 374 // reused for the result (but is not required to) because the input |
375 // is not used after the result is defined. We should consider adding | 375 // is not used after the result is defined. We should consider adding |
376 // this information to the input policy. | 376 // this information to the input policy. |
377 return LocationSummary::Make(1, Location::RequiresRegister()); | 377 return LocationSummary::Make(1, Location::RequiresRegister()); |
378 } | 378 } |
379 | 379 |
380 | 380 |
381 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 381 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
382 Register instance = locs()->in(0).reg(); | 382 Register instance = locs()->in(0).reg(); |
383 Register result = locs()->out().reg(); | 383 Register result = locs()->out().reg(); |
384 | 384 |
385 __ movq(result, FieldAddress(instance, field().Offset())); | 385 __ movq(result, FieldAddress(instance, field().Offset())); |
386 } | 386 } |
387 | 387 |
388 | 388 |
389 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { | 389 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { |
390 return LocationSummary::Make(0, Location::RequiresRegister()); | 390 return LocationSummary::Make(0, Location::RequiresRegister()); |
391 } | 391 } |
392 | 392 |
393 | 393 |
394 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 394 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
395 Register result = locs()->out().reg(); | 395 Register result = locs()->out().reg(); |
396 __ LoadObject(result, field()); | 396 __ LoadObject(result, field()); |
397 __ movq(result, FieldAddress(result, Field::value_offset())); | 397 __ movq(result, FieldAddress(result, Field::value_offset())); |
398 } | 398 } |
399 | 399 |
400 | 400 |
401 LocationSummary* InstanceOfComp::MakeLocationSummary() const { | 401 LocationSummary* InstanceOfComp::MakeLocationSummary() const { |
402 LocationSummary* summary = new LocationSummary(3, 0); | 402 LocationSummary* summary = new LocationSummary(3, 0); |
403 summary->set_in(0, Location::RegisterLocation(RAX)); | 403 summary->set_in(0, Location::RegisterLocation(RAX)); |
404 summary->set_in(1, Location::RegisterLocation(RCX)); | 404 summary->set_in(1, Location::RegisterLocation(RCX)); |
405 summary->set_in(2, Location::RegisterLocation(RDX)); | 405 summary->set_in(2, Location::RegisterLocation(RDX)); |
406 summary->set_out(Location::RegisterLocation(RAX)); | 406 summary->set_out(Location::RegisterLocation(RAX)); |
407 return summary; | 407 return summary; |
408 } | 408 } |
409 | 409 |
410 | 410 |
411 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 411 void InstanceOfComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
412 ASSERT(locs()->in(0).reg() == RAX); // Value. | 412 ASSERT(locs()->in(0).reg() == RAX); // Value. |
413 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. | 413 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. |
414 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. | 414 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. |
415 | 415 |
416 compiler->GenerateInstanceOf(cid(), | 416 compiler->GenerateInstanceOf(cid(), |
417 token_index(), | 417 token_index(), |
418 try_index(), | 418 try_index(), |
419 type(), | 419 type(), |
420 negate_result()); | 420 negate_result()); |
421 ASSERT(locs()->out().reg() == RAX); | 421 ASSERT(locs()->out().reg() == RAX); |
422 } | 422 } |
423 | 423 |
424 | 424 |
425 LocationSummary* CreateArrayComp::MakeLocationSummary() const { | 425 LocationSummary* CreateArrayComp::MakeLocationSummary() const { |
426 // TODO(regis): The elements of the array could be considered as arguments to | 426 // TODO(regis): The elements of the array could be considered as arguments to |
427 // CreateArrayComp, thereby making CreateArrayComp a call. | 427 // CreateArrayComp, thereby making CreateArrayComp a call. |
428 // For VerifyCallComputation to work, CreateArrayComp would need an | 428 // For VerifyCallComputation to work, CreateArrayComp would need an |
429 // ArgumentCount getter and an ArgumentAt getter. | 429 // ArgumentCount getter and an ArgumentAt getter. |
430 const intptr_t kNumInputs = 1; | 430 const intptr_t kNumInputs = 1; |
431 const intptr_t kNumTemps = 1; | 431 const intptr_t kNumTemps = 1; |
432 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 432 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
433 locs->set_in(0, Location::RegisterLocation(RBX)); | 433 locs->set_in(0, Location::RegisterLocation(RBX)); |
434 locs->set_temp(0, Location::RegisterLocation(R10)); | 434 locs->set_temp(0, Location::RegisterLocation(R10)); |
435 locs->set_out(Location::RegisterLocation(RAX)); | 435 locs->set_out(Location::RegisterLocation(RAX)); |
436 return locs; | 436 return locs; |
437 } | 437 } |
438 | 438 |
439 | 439 |
440 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 440 void CreateArrayComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
441 Register temp_reg = locs()->temp(0).reg(); | 441 Register temp_reg = locs()->temp(0).reg(); |
442 Register result_reg = locs()->out().reg(); | 442 Register result_reg = locs()->out().reg(); |
443 | 443 |
444 // 1. Allocate the array. R10 = length, RBX = element type. | 444 // 1. Allocate the array. R10 = length, RBX = element type. |
445 ASSERT(temp_reg == R10); | 445 ASSERT(temp_reg == R10); |
446 ASSERT(locs()->in(0).reg() == RBX); | 446 ASSERT(locs()->in(0).reg() == RBX); |
447 __ movq(temp_reg, Immediate(Smi::RawValue(ElementCount()))); | 447 __ movq(temp_reg, Immediate(Smi::RawValue(ElementCount()))); |
448 compiler->GenerateCall(token_index(), | 448 compiler->GenerateCall(token_index(), |
449 try_index(), | 449 try_index(), |
450 &StubCode::AllocateArrayLabel(), | 450 &StubCode::AllocateArrayLabel(), |
451 PcDescriptors::kOther); | 451 PcDescriptors::kOther); |
452 ASSERT(result_reg == RAX); | 452 ASSERT(result_reg == RAX); |
453 // 2. Initialize the array in result_reg with the element values. | 453 // 2. Initialize the array in result_reg with the element values. |
454 __ leaq(temp_reg, FieldAddress(result_reg, Array::data_offset())); | 454 __ leaq(temp_reg, FieldAddress(result_reg, Array::data_offset())); |
455 for (int i = ElementCount() - 1; i >= 0; --i) { | 455 for (int i = ElementCount() - 1; i >= 0; --i) { |
456 ASSERT(ElementAt(i)->IsUse()); | 456 ASSERT(ElementAt(i)->IsUse()); |
457 __ popq(Address(temp_reg, i * kWordSize)); | 457 __ popq(Address(temp_reg, i * kWordSize)); |
458 } | 458 } |
459 } | 459 } |
460 | 460 |
461 | 461 |
462 LocationSummary* AllocateObjectWithBoundsCheckComp:: | 462 LocationSummary* AllocateObjectWithBoundsCheckComp:: |
463 MakeLocationSummary() const { | 463 MakeLocationSummary() const { |
464 return LocationSummary::Make(2, Location::RequiresRegister()); | 464 return LocationSummary::Make(2, Location::RequiresRegister()); |
465 } | 465 } |
466 | 466 |
467 | 467 |
468 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( | 468 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( |
469 FlowGraphCompiler* compiler) { | 469 FlowGraphCompilerShared* compiler) { |
470 const Class& cls = Class::ZoneHandle(constructor().owner()); | 470 const Class& cls = Class::ZoneHandle(constructor().owner()); |
471 Register type_arguments = locs()->in(0).reg(); | 471 Register type_arguments = locs()->in(0).reg(); |
472 Register instantiator_type_arguments = locs()->in(1).reg(); | 472 Register instantiator_type_arguments = locs()->in(1).reg(); |
473 Register result = locs()->out().reg(); | 473 Register result = locs()->out().reg(); |
474 | 474 |
475 // Push the result place holder initialized to NULL. | 475 // Push the result place holder initialized to NULL. |
476 __ PushObject(Object::ZoneHandle()); | 476 __ PushObject(Object::ZoneHandle()); |
477 __ pushq(Immediate(Smi::RawValue(token_index()))); | 477 __ pushq(Immediate(Smi::RawValue(token_index()))); |
478 __ PushObject(cls); | 478 __ PushObject(cls); |
479 __ pushq(type_arguments); | 479 __ pushq(type_arguments); |
480 __ pushq(instantiator_type_arguments); | 480 __ pushq(instantiator_type_arguments); |
481 compiler->GenerateCallRuntime(cid(), | 481 compiler->GenerateCallRuntime(cid(), |
482 token_index(), | 482 token_index(), |
483 try_index(), | 483 try_index(), |
484 kAllocateObjectWithBoundsCheckRuntimeEntry); | 484 kAllocateObjectWithBoundsCheckRuntimeEntry); |
485 // Pop instantiator type arguments, type arguments, class, and | 485 // Pop instantiator type arguments, type arguments, class, and |
486 // source location. | 486 // source location. |
487 __ Drop(4); | 487 __ Drop(4); |
488 __ popq(result); // Pop new instance. | 488 __ popq(result); // Pop new instance. |
489 } | 489 } |
490 | 490 |
491 | 491 |
492 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { | 492 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { |
493 return LocationSummary::Make(1, Location::RequiresRegister()); | 493 return LocationSummary::Make(1, Location::RequiresRegister()); |
494 } | 494 } |
495 | 495 |
496 | 496 |
497 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 497 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
498 Register obj = locs()->in(0).reg(); | 498 Register obj = locs()->in(0).reg(); |
499 Register result = locs()->out().reg(); | 499 Register result = locs()->out().reg(); |
500 | 500 |
501 __ movq(result, FieldAddress(obj, offset_in_bytes())); | 501 __ movq(result, FieldAddress(obj, offset_in_bytes())); |
502 } | 502 } |
503 | 503 |
504 | 504 |
505 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { | 505 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { |
506 const intptr_t kNumInputs = 1; | 506 const intptr_t kNumInputs = 1; |
507 const intptr_t kNumTemps = 0; | 507 const intptr_t kNumTemps = 0; |
508 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 508 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
509 locs->set_in(0, Location::RequiresRegister()); | 509 locs->set_in(0, Location::RequiresRegister()); |
510 locs->set_out(Location::SameAsFirstInput()); | 510 locs->set_out(Location::SameAsFirstInput()); |
511 return locs; | 511 return locs; |
512 } | 512 } |
513 | 513 |
514 | 514 |
515 void InstantiateTypeArgumentsComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 515 void InstantiateTypeArgumentsComp::EmitNativeCode( |
| 516 FlowGraphCompilerShared* compiler) { |
516 Register instantiator_reg = locs()->in(0).reg(); | 517 Register instantiator_reg = locs()->in(0).reg(); |
517 Register result_reg = locs()->out().reg(); | 518 Register result_reg = locs()->out().reg(); |
518 | 519 |
519 // 'instantiator_reg' is the instantiator AbstractTypeArguments object | 520 // 'instantiator_reg' is the instantiator AbstractTypeArguments object |
520 // (or null). | 521 // (or null). |
521 // If the instantiator is null and if the type argument vector | 522 // If the instantiator is null and if the type argument vector |
522 // instantiated from null becomes a vector of Dynamic, then use null as | 523 // instantiated from null becomes a vector of Dynamic, then use null as |
523 // the type arguments. | 524 // the type arguments. |
524 Label type_arguments_instantiated; | 525 Label type_arguments_instantiated; |
525 const intptr_t len = type_arguments().Length(); | 526 const intptr_t len = type_arguments().Length(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 const intptr_t kNumInputs = 1; | 566 const intptr_t kNumInputs = 1; |
566 const intptr_t kNumTemps = 0; | 567 const intptr_t kNumTemps = 0; |
567 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 568 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
568 locs->set_in(0, Location::RequiresRegister()); | 569 locs->set_in(0, Location::RequiresRegister()); |
569 locs->set_out(Location::SameAsFirstInput()); | 570 locs->set_out(Location::SameAsFirstInput()); |
570 return locs; | 571 return locs; |
571 } | 572 } |
572 | 573 |
573 | 574 |
574 void ExtractConstructorTypeArgumentsComp::EmitNativeCode( | 575 void ExtractConstructorTypeArgumentsComp::EmitNativeCode( |
575 FlowGraphCompiler* compiler) { | 576 FlowGraphCompilerShared* compiler) { |
576 Register instantiator_reg = locs()->in(0).reg(); | 577 Register instantiator_reg = locs()->in(0).reg(); |
577 Register result_reg = locs()->out().reg(); | 578 Register result_reg = locs()->out().reg(); |
578 ASSERT(instantiator_reg == result_reg); | 579 ASSERT(instantiator_reg == result_reg); |
579 | 580 |
580 // instantiator_reg is the instantiator type argument vector, i.e. an | 581 // instantiator_reg is the instantiator type argument vector, i.e. an |
581 // AbstractTypeArguments object (or null). | 582 // AbstractTypeArguments object (or null). |
582 // If the instantiator is null and if the type argument vector | 583 // If the instantiator is null and if the type argument vector |
583 // instantiated from null becomes a vector of Dynamic, then use null as | 584 // instantiated from null becomes a vector of Dynamic, then use null as |
584 // the type arguments. | 585 // the type arguments. |
585 Label type_arguments_instantiated; | 586 Label type_arguments_instantiated; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 const intptr_t kNumInputs = 1; | 621 const intptr_t kNumInputs = 1; |
621 const intptr_t kNumTemps = 0; | 622 const intptr_t kNumTemps = 0; |
622 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 623 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
623 locs->set_in(0, Location::RequiresRegister()); | 624 locs->set_in(0, Location::RequiresRegister()); |
624 locs->set_out(Location::SameAsFirstInput()); | 625 locs->set_out(Location::SameAsFirstInput()); |
625 return locs; | 626 return locs; |
626 } | 627 } |
627 | 628 |
628 | 629 |
629 void ExtractConstructorInstantiatorComp::EmitNativeCode( | 630 void ExtractConstructorInstantiatorComp::EmitNativeCode( |
630 FlowGraphCompiler* compiler) { | 631 FlowGraphCompilerShared* compiler) { |
631 ASSERT(instantiator()->IsUse()); | 632 ASSERT(instantiator()->IsUse()); |
632 Register instantiator_reg = locs()->in(0).reg(); | 633 Register instantiator_reg = locs()->in(0).reg(); |
633 ASSERT(locs()->out().reg() == instantiator_reg); | 634 ASSERT(locs()->out().reg() == instantiator_reg); |
634 | 635 |
635 // instantiator_reg is the instantiator AbstractTypeArguments object | 636 // instantiator_reg is the instantiator AbstractTypeArguments object |
636 // (or null). If the instantiator is null and if the type argument vector | 637 // (or null). If the instantiator is null and if the type argument vector |
637 // instantiated from null becomes a vector of Dynamic, then use null as | 638 // instantiated from null becomes a vector of Dynamic, then use null as |
638 // the type arguments and do not pass the instantiator. | 639 // the type arguments and do not pass the instantiator. |
639 Label done; | 640 Label done; |
640 const intptr_t len = type_arguments().Length(); | 641 const intptr_t len = type_arguments().Length(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 LocationSummary* AllocateContextComp::MakeLocationSummary() const { | 684 LocationSummary* AllocateContextComp::MakeLocationSummary() const { |
684 const intptr_t kNumInputs = 0; | 685 const intptr_t kNumInputs = 0; |
685 const intptr_t kNumTemps = 1; | 686 const intptr_t kNumTemps = 1; |
686 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 687 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
687 locs->set_temp(0, Location::RegisterLocation(R10)); | 688 locs->set_temp(0, Location::RegisterLocation(R10)); |
688 locs->set_out(Location::RegisterLocation(RAX)); | 689 locs->set_out(Location::RegisterLocation(RAX)); |
689 return locs; | 690 return locs; |
690 } | 691 } |
691 | 692 |
692 | 693 |
693 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 694 void AllocateContextComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
694 ASSERT(locs()->temp(0).reg() == R10); | 695 ASSERT(locs()->temp(0).reg() == R10); |
695 | 696 |
696 __ movq(R10, Immediate(num_context_variables())); | 697 __ movq(R10, Immediate(num_context_variables())); |
697 const ExternalLabel label("alloc_context", | 698 const ExternalLabel label("alloc_context", |
698 StubCode::AllocateContextEntryPoint()); | 699 StubCode::AllocateContextEntryPoint()); |
699 compiler->GenerateCall(token_index(), | 700 compiler->GenerateCall(token_index(), |
700 try_index(), | 701 try_index(), |
701 &label, | 702 &label, |
702 PcDescriptors::kOther); | 703 PcDescriptors::kOther); |
703 } | 704 } |
704 | 705 |
705 | 706 |
706 LocationSummary* CloneContextComp::MakeLocationSummary() const { | 707 LocationSummary* CloneContextComp::MakeLocationSummary() const { |
707 return LocationSummary::Make(1, Location::RequiresRegister()); | 708 return LocationSummary::Make(1, Location::RequiresRegister()); |
708 } | 709 } |
709 | 710 |
710 | 711 |
711 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 712 void CloneContextComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
712 Register context_value = locs()->in(0).reg(); | 713 Register context_value = locs()->in(0).reg(); |
713 Register result = locs()->out().reg(); | 714 Register result = locs()->out().reg(); |
714 | 715 |
715 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 716 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
716 __ pushq(context_value); | 717 __ pushq(context_value); |
717 compiler->GenerateCallRuntime(cid(), | 718 compiler->GenerateCallRuntime(cid(), |
718 token_index(), | 719 token_index(), |
719 try_index(), | 720 try_index(), |
720 kCloneContextRuntimeEntry); | 721 kCloneContextRuntimeEntry); |
721 __ popq(result); // Remove argument. | 722 __ popq(result); // Remove argument. |
722 __ popq(result); // Get result (cloned context). | 723 __ popq(result); // Get result (cloned context). |
723 } | 724 } |
724 | 725 |
725 | 726 |
726 LocationSummary* CatchEntryComp::MakeLocationSummary() const { | 727 LocationSummary* CatchEntryComp::MakeLocationSummary() const { |
727 return LocationSummary::Make(0, Location::NoLocation()); | 728 return LocationSummary::Make(0, Location::NoLocation()); |
728 } | 729 } |
729 | 730 |
730 | 731 |
731 // Restore stack and initialize the two exception variables: | 732 // Restore stack and initialize the two exception variables: |
732 // exception and stack trace variables. | 733 // exception and stack trace variables. |
733 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 734 void CatchEntryComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
734 // Restore RSP from RBP as we are coming from a throw and the code for | 735 // Restore RSP from RBP as we are coming from a throw and the code for |
735 // popping arguments has not been run. | 736 // popping arguments has not been run. |
736 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; | 737 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; |
737 ASSERT(locals_space_size >= 0); | 738 ASSERT(locals_space_size >= 0); |
738 const intptr_t offset_size = | 739 const intptr_t offset_size = |
739 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; | 740 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; |
740 __ leaq(RSP, Address(RBP, offset_size)); | 741 __ leaq(RSP, Address(RBP, offset_size)); |
741 | 742 |
742 ASSERT(!exception_var().is_captured()); | 743 ASSERT(!exception_var().is_captured()); |
743 ASSERT(!stacktrace_var().is_captured()); | 744 ASSERT(!stacktrace_var().is_captured()); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 summary->set_in(0, Location::RequiresRegister()); | 785 summary->set_in(0, Location::RequiresRegister()); |
785 summary->set_in(1, Location::RequiresRegister()); | 786 summary->set_in(1, Location::RequiresRegister()); |
786 summary->set_out(Location::SameAsFirstInput()); | 787 summary->set_out(Location::SameAsFirstInput()); |
787 summary->set_temp(0, Location::RequiresRegister()); | 788 summary->set_temp(0, Location::RequiresRegister()); |
788 return summary; | 789 return summary; |
789 } | 790 } |
790 } | 791 } |
791 | 792 |
792 | 793 |
793 // TODO(srdjan): Implement variations. | 794 // TODO(srdjan): Implement variations. |
794 static bool TryEmitSmiBinaryOp(FlowGraphCompiler* compiler, | 795 static bool TryEmitSmiBinaryOp(FlowGraphCompilerShared* compiler, |
795 BinaryOpComp* comp) { | 796 BinaryOpComp* comp) { |
796 ASSERT((comp->ic_data() != NULL)); | 797 ASSERT((comp->ic_data() != NULL)); |
797 const ICData& ic_data = *comp->ic_data(); | 798 const ICData& ic_data = *comp->ic_data(); |
798 if (ic_data.IsNull()) return false; | 799 if (ic_data.IsNull()) return false; |
799 if (ic_data.num_args_tested() != 2) return false; | 800 if (ic_data.num_args_tested() != 2) return false; |
800 if (ic_data.NumberOfChecks() != 1) return false; | 801 if (ic_data.NumberOfChecks() != 1) return false; |
801 Function& target = Function::Handle(); | 802 Function& target = Function::Handle(); |
802 GrowableArray<const Class*> classes; | 803 GrowableArray<const Class*> classes; |
803 ic_data.GetCheckAt(0, &classes, &target); | 804 ic_data.GetCheckAt(0, &classes, &target); |
804 const Class& smi_class = | 805 const Class& smi_class = |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 UNREACHABLE(); | 930 UNREACHABLE(); |
930 return false; | 931 return false; |
931 } | 932 } |
932 default: | 933 default: |
933 UNREACHABLE(); | 934 UNREACHABLE(); |
934 return false; | 935 return false; |
935 } | 936 } |
936 return true; | 937 return true; |
937 } | 938 } |
938 | 939 |
939 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 940 void BinaryOpComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
940 if (TryEmitSmiBinaryOp(compiler, this)) { | 941 if (TryEmitSmiBinaryOp(compiler, this)) { |
941 // Operation inlined. | 942 // Operation inlined. |
942 return; | 943 return; |
943 } | 944 } |
944 // TODO(srdjan): Remove this code once BinaryOpComp has been implemeneted | 945 // TODO(srdjan): Remove this code once BinaryOpComp has been implemeneted |
945 // for all intended operations. | 946 // for all intended operations. |
946 Register left = locs()->in(0).reg(); | 947 Register left = locs()->in(0).reg(); |
947 Register right = locs()->in(1).reg(); | 948 Register right = locs()->in(1).reg(); |
948 __ pushq(left); | 949 __ pushq(left); |
949 __ pushq(right); | 950 __ pushq(right); |
950 InstanceCallComp* instance_call_comp = instance_call(); | 951 InstanceCallComp* instance_call_comp = instance_call(); |
951 instance_call_comp->EmitNativeCode(compiler); | 952 instance_call_comp->EmitNativeCode(compiler); |
952 if (locs()->out().reg() != RAX) { | 953 if (locs()->out().reg() != RAX) { |
953 __ movq(locs()->out().reg(), RAX); | 954 __ movq(locs()->out().reg(), RAX); |
954 } | 955 } |
955 } | 956 } |
956 | 957 |
957 | 958 |
958 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { | 959 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { |
959 const intptr_t kNumInputs = 1; | 960 const intptr_t kNumInputs = 1; |
960 const intptr_t kNumTemps = 0; | 961 const intptr_t kNumTemps = 0; |
961 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 962 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
962 summary->set_in(0, Location::RequiresRegister()); | 963 summary->set_in(0, Location::RequiresRegister()); |
963 summary->set_out(Location::SameAsFirstInput()); | 964 summary->set_out(Location::SameAsFirstInput()); |
964 return summary; | 965 return summary; |
965 } | 966 } |
966 | 967 |
967 | 968 |
968 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 969 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
969 const ICData& ic_data = *instance_call()->ic_data(); | 970 const ICData& ic_data = *instance_call()->ic_data(); |
970 ASSERT(!ic_data.IsNull()); | 971 ASSERT(!ic_data.IsNull()); |
971 ASSERT(ic_data.num_args_tested() == 1); | 972 ASSERT(ic_data.num_args_tested() == 1); |
972 // TODO(srdjan): Implement for more checks. | 973 // TODO(srdjan): Implement for more checks. |
973 ASSERT(ic_data.NumberOfChecks() == 1); | 974 ASSERT(ic_data.NumberOfChecks() == 1); |
974 Class& test_class = Class::Handle(); | 975 Class& test_class = Class::Handle(); |
975 Function& target = Function::Handle(); | 976 Function& target = Function::Handle(); |
976 ic_data.GetOneClassCheckAt(0, &test_class, &target); | 977 ic_data.GetOneClassCheckAt(0, &test_class, &target); |
977 | 978 |
978 Register value = locs()->in(0).reg(); | 979 Register value = locs()->in(0).reg(); |
(...skipping 30 matching lines...) Expand all Loading... |
1009 const intptr_t kNumInputs = 1; | 1010 const intptr_t kNumInputs = 1; |
1010 const intptr_t kNumTemps = 1; // Needed for doubles. | 1011 const intptr_t kNumTemps = 1; // Needed for doubles. |
1011 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1012 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
1012 summary->set_in(0, Location::RequiresRegister()); | 1013 summary->set_in(0, Location::RequiresRegister()); |
1013 summary->set_out(Location::SameAsFirstInput()); | 1014 summary->set_out(Location::SameAsFirstInput()); |
1014 summary->set_temp(0, Location::RequiresRegister()); | 1015 summary->set_temp(0, Location::RequiresRegister()); |
1015 return summary; | 1016 return summary; |
1016 } | 1017 } |
1017 | 1018 |
1018 | 1019 |
1019 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1020 void NumberNegateComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
1020 const ICData& ic_data = *instance_call()->ic_data(); | 1021 const ICData& ic_data = *instance_call()->ic_data(); |
1021 ASSERT(!ic_data.IsNull()); | 1022 ASSERT(!ic_data.IsNull()); |
1022 ASSERT(ic_data.num_args_tested() == 1); | 1023 ASSERT(ic_data.num_args_tested() == 1); |
1023 | 1024 |
1024 // TODO(srdjan): Implement for more checks. | 1025 // TODO(srdjan): Implement for more checks. |
1025 ASSERT(ic_data.NumberOfChecks() == 1); | 1026 ASSERT(ic_data.NumberOfChecks() == 1); |
1026 Class& test_class = Class::Handle(); | 1027 Class& test_class = Class::Handle(); |
1027 Function& target = Function::Handle(); | 1028 Function& target = Function::Handle(); |
1028 ic_data.GetOneClassCheckAt(0, &test_class, &target); | 1029 ic_data.GetOneClassCheckAt(0, &test_class, &target); |
1029 | 1030 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1063 } else { | 1064 } else { |
1064 UNREACHABLE(); | 1065 UNREACHABLE(); |
1065 } | 1066 } |
1066 } | 1067 } |
1067 | 1068 |
1068 } // namespace dart | 1069 } // namespace dart |
1069 | 1070 |
1070 #undef __ | 1071 #undef __ |
1071 | 1072 |
1072 #endif // defined TARGET_ARCH_X64 | 1073 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |