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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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" |
(...skipping 12 matching lines...) Expand all Loading... |
23 | 23 |
24 // Generic summary for call instructions that have all arguments pushed | 24 // Generic summary for call instructions that have all arguments pushed |
25 // on the stack and return the result in a fixed register EAX. | 25 // on the stack and return the result in a fixed register EAX. |
26 LocationSummary* Computation::MakeCallSummary() { | 26 LocationSummary* Computation::MakeCallSummary() { |
27 LocationSummary* result = new LocationSummary(0, 0); | 27 LocationSummary* result = new LocationSummary(0, 0); |
28 result->set_out(Location::RegisterLocation(EAX)); | 28 result->set_out(Location::RegisterLocation(EAX)); |
29 return result; | 29 return result; |
30 } | 30 } |
31 | 31 |
32 | 32 |
33 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 33 void BindInstr::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
34 computation()->EmitNativeCode(compiler); | 34 computation()->EmitNativeCode(compiler); |
35 __ pushl(locs()->out().reg()); | 35 __ pushl(locs()->out().reg()); |
36 } | 36 } |
37 | 37 |
38 | 38 |
39 LocationSummary* ReturnInstr::MakeLocationSummary() const { | 39 LocationSummary* ReturnInstr::MakeLocationSummary() const { |
40 const intptr_t kNumInputs = 1; | 40 const intptr_t kNumInputs = 1; |
41 const intptr_t kNumTemps = 1; | 41 const intptr_t kNumTemps = 1; |
42 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 42 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
43 locs->set_in(0, Location::RegisterLocation(EAX)); | 43 locs->set_in(0, Location::RegisterLocation(EAX)); |
44 locs->set_temp(0, Location::RequiresRegister()); | 44 locs->set_temp(0, Location::RequiresRegister()); |
45 return locs; | 45 return locs; |
46 } | 46 } |
47 | 47 |
48 | 48 |
49 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 49 void ReturnInstr::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
50 Register result = locs()->in(0).reg(); | 50 Register result = locs()->in(0).reg(); |
51 Register temp = locs()->temp(0).reg(); | 51 Register temp = locs()->temp(0).reg(); |
52 ASSERT(result == EAX); | 52 ASSERT(result == EAX); |
53 if (!compiler->is_optimizing()) { | 53 if (!compiler->is_optimizing()) { |
54 // Count only in unoptimized code. | 54 // Count only in unoptimized code. |
55 // TODO(srdjan): Replace the counting code with a type feedback | 55 // TODO(srdjan): Replace the counting code with a type feedback |
56 // collection and counting stub. | 56 // collection and counting stub. |
57 const Function& function = | 57 const Function& function = |
58 Function::ZoneHandle(compiler->parsed_function().function().raw()); | 58 Function::ZoneHandle(compiler->parsed_function().function().raw()); |
59 __ LoadObject(temp, function); | 59 __ LoadObject(temp, function); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor. | 105 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor. |
106 return result; | 106 return result; |
107 } | 107 } |
108 | 108 |
109 | 109 |
110 LocationSummary* LoadLocalComp::MakeLocationSummary() const { | 110 LocationSummary* LoadLocalComp::MakeLocationSummary() const { |
111 return LocationSummary::Make(0, Location::RequiresRegister()); | 111 return LocationSummary::Make(0, Location::RequiresRegister()); |
112 } | 112 } |
113 | 113 |
114 | 114 |
115 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 115 void LoadLocalComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
116 Register result = locs()->out().reg(); | 116 Register result = locs()->out().reg(); |
117 __ movl(result, Address(EBP, local().index() * kWordSize)); | 117 __ movl(result, Address(EBP, local().index() * kWordSize)); |
118 } | 118 } |
119 | 119 |
120 | 120 |
121 LocationSummary* StoreLocalComp::MakeLocationSummary() const { | 121 LocationSummary* StoreLocalComp::MakeLocationSummary() const { |
122 return LocationSummary::Make(1, Location::SameAsFirstInput()); | 122 return LocationSummary::Make(1, Location::SameAsFirstInput()); |
123 } | 123 } |
124 | 124 |
125 | 125 |
126 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 126 void StoreLocalComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
127 Register value = locs()->in(0).reg(); | 127 Register value = locs()->in(0).reg(); |
128 Register result = locs()->out().reg(); | 128 Register result = locs()->out().reg(); |
129 ASSERT(result == value); // Assert that register assignment is correct. | 129 ASSERT(result == value); // Assert that register assignment is correct. |
130 __ movl(Address(EBP, local().index() * kWordSize), value); | 130 __ movl(Address(EBP, local().index() * kWordSize), value); |
131 } | 131 } |
132 | 132 |
133 | 133 |
134 LocationSummary* ConstantVal::MakeLocationSummary() const { | 134 LocationSummary* ConstantVal::MakeLocationSummary() const { |
135 return LocationSummary::Make(0, Location::RequiresRegister()); | 135 return LocationSummary::Make(0, Location::RequiresRegister()); |
136 } | 136 } |
137 | 137 |
138 | 138 |
139 void ConstantVal::EmitNativeCode(FlowGraphCompiler* compiler) { | 139 void ConstantVal::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
140 Register result = locs()->out().reg(); | 140 Register result = locs()->out().reg(); |
141 if (value().IsSmi()) { | 141 if (value().IsSmi()) { |
142 int32_t imm = reinterpret_cast<int32_t>(value().raw()); | 142 int32_t imm = reinterpret_cast<int32_t>(value().raw()); |
143 __ movl(result, Immediate(imm)); | 143 __ movl(result, Immediate(imm)); |
144 } else { | 144 } else { |
145 __ LoadObject(result, value()); | 145 __ LoadObject(result, value()); |
146 } | 146 } |
147 } | 147 } |
148 | 148 |
149 | 149 |
150 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { | 150 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { |
151 LocationSummary* summary = new LocationSummary(3, 0); | 151 LocationSummary* summary = new LocationSummary(3, 0); |
152 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. | 152 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. |
153 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator. | 153 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator. |
154 summary->set_in(2, Location::RegisterLocation(EDX)); // Type arguments. | 154 summary->set_in(2, Location::RegisterLocation(EDX)); // Type arguments. |
155 summary->set_out(Location::RegisterLocation(EAX)); | 155 summary->set_out(Location::RegisterLocation(EAX)); |
156 return summary; | 156 return summary; |
157 } | 157 } |
158 | 158 |
159 | 159 |
160 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 160 void AssertBooleanComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
161 Register obj = locs()->in(0).reg(); | 161 Register obj = locs()->in(0).reg(); |
162 Register result = locs()->out().reg(); | 162 Register result = locs()->out().reg(); |
163 | 163 |
164 // Check that the type of the value is allowed in conditional context. | 164 // Check that the type of the value is allowed in conditional context. |
165 // Call the runtime if the object is not bool::true or bool::false. | 165 // Call the runtime if the object is not bool::true or bool::false. |
166 Label done; | 166 Label done; |
167 __ CompareObject(obj, Bool::ZoneHandle(Bool::True())); | 167 __ CompareObject(obj, Bool::ZoneHandle(Bool::True())); |
168 __ j(EQUAL, &done, Assembler::kNearJump); | 168 __ j(EQUAL, &done, Assembler::kNearJump); |
169 __ CompareObject(obj, Bool::ZoneHandle(Bool::False())); | 169 __ CompareObject(obj, Bool::ZoneHandle(Bool::False())); |
170 __ j(EQUAL, &done, Assembler::kNearJump); | 170 __ j(EQUAL, &done, Assembler::kNearJump); |
(...skipping 14 matching lines...) Expand all Loading... |
185 | 185 |
186 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { | 186 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { |
187 LocationSummary* locs = new LocationSummary(2, 0); | 187 LocationSummary* locs = new LocationSummary(2, 0); |
188 locs->set_in(0, Location::RequiresRegister()); | 188 locs->set_in(0, Location::RequiresRegister()); |
189 locs->set_in(1, Location::RequiresRegister()); | 189 locs->set_in(1, Location::RequiresRegister()); |
190 locs->set_out(Location::RegisterLocation(EAX)); | 190 locs->set_out(Location::RegisterLocation(EAX)); |
191 return locs; | 191 return locs; |
192 } | 192 } |
193 | 193 |
194 | 194 |
195 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 195 void EqualityCompareComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
196 Register left = locs()->in(0).reg(); | 196 Register left = locs()->in(0).reg(); |
197 Register right = locs()->in(1).reg(); | 197 Register right = locs()->in(1).reg(); |
198 Register result = locs()->out().reg(); | 198 Register result = locs()->out().reg(); |
199 ASSERT(locs()->out().reg() == EAX); | 199 ASSERT(locs()->out().reg() == EAX); |
200 | 200 |
201 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 201 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
202 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 202 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
203 const Immediate raw_null = | 203 const Immediate raw_null = |
204 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 204 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
205 Label done, load_true, non_null_compare; | 205 Label done, load_true, non_null_compare; |
(...skipping 30 matching lines...) Expand all Loading... |
236 LocationSummary* NativeCallComp::MakeLocationSummary() const { | 236 LocationSummary* NativeCallComp::MakeLocationSummary() const { |
237 LocationSummary* locs = new LocationSummary(0, 3); | 237 LocationSummary* locs = new LocationSummary(0, 3); |
238 locs->set_temp(0, Location::RegisterLocation(EAX)); | 238 locs->set_temp(0, Location::RegisterLocation(EAX)); |
239 locs->set_temp(1, Location::RegisterLocation(ECX)); | 239 locs->set_temp(1, Location::RegisterLocation(ECX)); |
240 locs->set_temp(2, Location::RegisterLocation(EDX)); | 240 locs->set_temp(2, Location::RegisterLocation(EDX)); |
241 locs->set_out(Location::RequiresRegister()); | 241 locs->set_out(Location::RequiresRegister()); |
242 return locs; | 242 return locs; |
243 } | 243 } |
244 | 244 |
245 | 245 |
246 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 246 void NativeCallComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
247 ASSERT(locs()->temp(0).reg() == EAX); | 247 ASSERT(locs()->temp(0).reg() == EAX); |
248 ASSERT(locs()->temp(1).reg() == ECX); | 248 ASSERT(locs()->temp(1).reg() == ECX); |
249 ASSERT(locs()->temp(2).reg() == EDX); | 249 ASSERT(locs()->temp(2).reg() == EDX); |
250 Register result = locs()->out().reg(); | 250 Register result = locs()->out().reg(); |
251 // Push the result place holder initialized to NULL. | 251 // Push the result place holder initialized to NULL. |
252 __ PushObject(Object::ZoneHandle()); | 252 __ PushObject(Object::ZoneHandle()); |
253 // Pass a pointer to the first argument in EAX. | 253 // Pass a pointer to the first argument in EAX. |
254 if (!has_optional_parameters()) { | 254 if (!has_optional_parameters()) { |
255 __ leal(EAX, Address(EBP, (1 + argument_count()) * kWordSize)); | 255 __ leal(EAX, Address(EBP, (1 + argument_count()) * kWordSize)); |
256 } else { | 256 } else { |
257 __ leal(EAX, | 257 __ leal(EAX, |
258 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); | 258 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); |
259 } | 259 } |
260 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); | 260 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); |
261 __ movl(EDX, Immediate(argument_count())); | 261 __ movl(EDX, Immediate(argument_count())); |
262 compiler->GenerateCall(token_index(), | 262 compiler->GenerateCall(token_index(), |
263 try_index(), | 263 try_index(), |
264 &StubCode::CallNativeCFunctionLabel(), | 264 &StubCode::CallNativeCFunctionLabel(), |
265 PcDescriptors::kOther); | 265 PcDescriptors::kOther); |
266 __ popl(result); | 266 __ popl(result); |
267 } | 267 } |
268 | 268 |
269 | 269 |
270 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { | 270 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { |
271 const intptr_t kNumInputs = 3; | 271 const intptr_t kNumInputs = 3; |
272 return LocationSummary::Make(kNumInputs, Location::NoLocation()); | 272 return LocationSummary::Make(kNumInputs, Location::NoLocation()); |
273 } | 273 } |
274 | 274 |
275 | 275 |
276 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 276 void StoreIndexedComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
277 Register receiver = locs()->in(0).reg(); | 277 Register receiver = locs()->in(0).reg(); |
278 Register index = locs()->in(1).reg(); | 278 Register index = locs()->in(1).reg(); |
279 Register value = locs()->in(2).reg(); | 279 Register value = locs()->in(2).reg(); |
280 | 280 |
281 const String& function_name = | 281 const String& function_name = |
282 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); | 282 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); |
283 | 283 |
284 __ pushl(receiver); | 284 __ pushl(receiver); |
285 __ pushl(index); | 285 __ pushl(index); |
286 __ pushl(value); | 286 __ pushl(value); |
287 const intptr_t kNumArguments = 3; | 287 const intptr_t kNumArguments = 3; |
288 const intptr_t kNumArgsChecked = 1; // Type-feedback. | 288 const intptr_t kNumArgsChecked = 1; // Type-feedback. |
289 compiler->GenerateInstanceCall(cid(), | 289 compiler->GenerateInstanceCall(cid(), |
290 token_index(), | 290 token_index(), |
291 try_index(), | 291 try_index(), |
292 function_name, | 292 function_name, |
293 kNumArguments, | 293 kNumArguments, |
294 Array::ZoneHandle(), // No optional arguments. | 294 Array::ZoneHandle(), // No optional arguments. |
295 kNumArgsChecked); | 295 kNumArgsChecked); |
296 } | 296 } |
297 | 297 |
298 | 298 |
299 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { | 299 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { |
300 const intptr_t kNumInputs = 2; | 300 const intptr_t kNumInputs = 2; |
301 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); | 301 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); |
302 return NULL; | |
303 } | 302 } |
304 | 303 |
305 | 304 |
306 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 305 void InstanceSetterComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
307 Register receiver = locs()->in(0).reg(); | 306 Register receiver = locs()->in(0).reg(); |
308 Register value = locs()->in(1).reg(); | 307 Register value = locs()->in(1).reg(); |
309 Register result = locs()->out().reg(); | 308 Register result = locs()->out().reg(); |
310 | 309 |
311 // Preserve the value (second argument) under the arguments as the result | 310 // Preserve the value (second argument) under the arguments as the result |
312 // of the computation, then call the setter. | 311 // of the computation, then call the setter. |
313 const String& function_name = | 312 const String& function_name = |
314 String::ZoneHandle(Field::SetterSymbol(field_name())); | 313 String::ZoneHandle(Field::SetterSymbol(field_name())); |
315 | 314 |
316 // Insert a copy of the second (last) argument under the arguments. | 315 // Insert a copy of the second (last) argument under the arguments. |
317 // TODO(fschneider): Avoid preserving the value if the result is not used. | 316 // TODO(fschneider): Avoid preserving the value if the result is not used. |
318 __ pushl(value); | 317 __ pushl(value); |
319 __ pushl(receiver); | 318 __ pushl(receiver); |
320 __ pushl(value); | 319 __ pushl(value); |
321 const intptr_t kArgumentCount = 2; | 320 const intptr_t kArgumentCount = 2; |
322 const intptr_t kCheckedArgumentCount = 1; | 321 const intptr_t kCheckedArgumentCount = 1; |
323 compiler->GenerateInstanceCall(cid(), | 322 compiler->GenerateInstanceCall(cid(), |
324 token_index(), | 323 token_index(), |
325 try_index(), | 324 try_index(), |
326 function_name, | 325 function_name, |
327 kArgumentCount, | 326 kArgumentCount, |
328 Array::ZoneHandle(), | 327 Array::ZoneHandle(), |
329 kCheckedArgumentCount); | 328 kCheckedArgumentCount); |
330 __ popl(result); | 329 __ popl(result); |
331 } | 330 } |
332 | 331 |
333 | 332 |
334 LocationSummary* StaticSetterComp::MakeLocationSummary() const { | 333 LocationSummary* StaticSetterComp::MakeLocationSummary() const { |
335 return NULL; | 334 const intptr_t kNumInputs = 1; |
| 335 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); |
336 } | 336 } |
337 | 337 |
338 | 338 |
339 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 339 void StaticSetterComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
340 UNIMPLEMENTED(); | 340 Register value = locs()->in(0).reg(); |
| 341 Register result = locs()->out().reg(); |
| 342 |
| 343 // Preserve the argument as the result of the computation, |
| 344 // then call the setter. |
| 345 |
| 346 // Duplicate the argument. |
| 347 // TODO(fschneider): Avoid preserving the value if the result is not used. |
| 348 __ pushl(value); |
| 349 __ pushl(value); |
| 350 compiler->GenerateStaticCall(cid(), |
| 351 token_index(), |
| 352 try_index(), |
| 353 setter_function(), |
| 354 1, |
| 355 Array::ZoneHandle()); |
| 356 __ popl(result); |
341 } | 357 } |
342 | 358 |
343 | 359 |
344 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { | 360 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { |
345 return NULL; | 361 // TODO(fschneider): For this instruction the input register may be |
| 362 // reused for the result (but is not required to) because the input |
| 363 // is not used after the result is defined. We should consider adding |
| 364 // this information to the input policy. |
| 365 return LocationSummary::Make(1, Location::RequiresRegister()); |
346 } | 366 } |
347 | 367 |
348 | 368 |
349 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 369 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
350 UNIMPLEMENTED(); | 370 Register instance = locs()->in(0).reg(); |
| 371 Register result = locs()->out().reg(); |
| 372 |
| 373 __ movl(result, FieldAddress(instance, field().Offset())); |
351 } | 374 } |
352 | 375 |
353 | 376 |
354 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { | 377 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { |
355 return LocationSummary::Make(0, Location::RequiresRegister()); | 378 return LocationSummary::Make(0, Location::RequiresRegister()); |
356 } | 379 } |
357 | 380 |
358 | 381 |
359 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 382 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
360 Register result = locs()->out().reg(); | 383 Register result = locs()->out().reg(); |
361 __ LoadObject(result, field()); | 384 __ LoadObject(result, field()); |
362 __ movl(result, FieldAddress(result, Field::value_offset())); | 385 __ movl(result, FieldAddress(result, Field::value_offset())); |
363 } | 386 } |
364 | 387 |
365 | 388 |
366 LocationSummary* InstanceOfComp::MakeLocationSummary() const { | 389 LocationSummary* InstanceOfComp::MakeLocationSummary() const { |
367 LocationSummary* summary = new LocationSummary(3, 0); | 390 LocationSummary* summary = new LocationSummary(3, 0); |
368 summary->set_in(0, Location::RegisterLocation(EAX)); | 391 summary->set_in(0, Location::RegisterLocation(EAX)); |
369 summary->set_in(1, Location::RegisterLocation(ECX)); | 392 summary->set_in(1, Location::RegisterLocation(ECX)); |
370 summary->set_in(2, Location::RegisterLocation(EDX)); | 393 summary->set_in(2, Location::RegisterLocation(EDX)); |
371 summary->set_out(Location::RegisterLocation(EAX)); | 394 summary->set_out(Location::RegisterLocation(EAX)); |
372 return summary; | 395 return summary; |
373 } | 396 } |
374 | 397 |
375 | 398 |
376 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 399 void InstanceOfComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
377 ASSERT(locs()->in(0).reg() == EAX); // Value. | 400 ASSERT(locs()->in(0).reg() == EAX); // Value. |
378 ASSERT(locs()->in(1).reg() == ECX); // Instantiator. | 401 ASSERT(locs()->in(1).reg() == ECX); // Instantiator. |
379 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. | 402 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. |
380 | 403 |
381 compiler->GenerateInstanceOf(cid(), | 404 compiler->GenerateInstanceOf(cid(), |
382 token_index(), | 405 token_index(), |
383 try_index(), | 406 try_index(), |
384 type(), | 407 type(), |
385 negate_result()); | 408 negate_result()); |
386 ASSERT(locs()->out().reg() == EAX); | 409 ASSERT(locs()->out().reg() == EAX); |
387 } | 410 } |
388 | 411 |
389 | 412 |
390 LocationSummary* CreateArrayComp::MakeLocationSummary() const { | 413 LocationSummary* CreateArrayComp::MakeLocationSummary() const { |
391 // TODO(regis): The elements of the array could be considered as arguments to | 414 // TODO(regis): The elements of the array could be considered as arguments to |
392 // CreateArrayComp, thereby making CreateArrayComp a call. | 415 // CreateArrayComp, thereby making CreateArrayComp a call. |
393 // For VerifyCallComputation to work, CreateArrayComp would need an | 416 // For VerifyCallComputation to work, CreateArrayComp would need an |
394 // ArgumentCount getter and an ArgumentAt getter. | 417 // ArgumentCount getter and an ArgumentAt getter. |
395 const intptr_t kNumInputs = 1; | 418 const intptr_t kNumInputs = 1; |
396 const intptr_t kNumTemps = 1; | 419 const intptr_t kNumTemps = 1; |
397 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 420 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
398 locs->set_in(0, Location::RegisterLocation(ECX)); | 421 locs->set_in(0, Location::RegisterLocation(ECX)); |
399 locs->set_temp(0, Location::RegisterLocation(EDX)); | 422 locs->set_temp(0, Location::RegisterLocation(EDX)); |
400 locs->set_out(Location::RegisterLocation(EAX)); | 423 locs->set_out(Location::RegisterLocation(EAX)); |
401 return locs; | 424 return locs; |
402 } | 425 } |
403 | 426 |
404 | 427 |
405 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 428 void CreateArrayComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
406 Register temp_reg = locs()->temp(0).reg(); | 429 Register temp_reg = locs()->temp(0).reg(); |
407 Register result_reg = locs()->out().reg(); | 430 Register result_reg = locs()->out().reg(); |
408 ASSERT(temp_reg == EDX); | 431 ASSERT(temp_reg == EDX); |
409 ASSERT(locs()->in(0).reg() == ECX); | 432 ASSERT(locs()->in(0).reg() == ECX); |
410 // 1. Allocate the array. EDX = length, ECX = element type. | 433 // 1. Allocate the array. EDX = length, ECX = element type. |
411 __ movl(EDX, Immediate(Smi::RawValue(ElementCount()))); | 434 __ movl(EDX, Immediate(Smi::RawValue(ElementCount()))); |
412 compiler->GenerateCall(token_index(), | 435 compiler->GenerateCall(token_index(), |
413 try_index(), | 436 try_index(), |
414 &StubCode::AllocateArrayLabel(), | 437 &StubCode::AllocateArrayLabel(), |
415 PcDescriptors::kOther); | 438 PcDescriptors::kOther); |
416 ASSERT(result_reg == EAX); | 439 ASSERT(result_reg == EAX); |
417 // Pop the element values from the stack into the array. | 440 // Pop the element values from the stack into the array. |
418 __ leal(temp_reg, FieldAddress(result_reg, Array::data_offset())); | 441 __ leal(temp_reg, FieldAddress(result_reg, Array::data_offset())); |
419 for (int i = ElementCount() - 1; i >= 0; --i) { | 442 for (int i = ElementCount() - 1; i >= 0; --i) { |
420 ASSERT(ElementAt(i)->IsUse()); | 443 ASSERT(ElementAt(i)->IsUse()); |
421 __ popl(Address(temp_reg, i * kWordSize)); | 444 __ popl(Address(temp_reg, i * kWordSize)); |
422 } | 445 } |
423 } | 446 } |
424 | 447 |
425 | 448 |
426 LocationSummary* | 449 LocationSummary* |
427 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const { | 450 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const { |
428 return LocationSummary::Make(2, Location::RequiresRegister()); | 451 return LocationSummary::Make(2, Location::RequiresRegister()); |
429 } | 452 } |
430 | 453 |
431 | 454 |
432 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( | 455 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( |
433 FlowGraphCompiler* compiler) { | 456 FlowGraphCompilerShared* compiler) { |
434 const Class& cls = Class::ZoneHandle(constructor().owner()); | 457 const Class& cls = Class::ZoneHandle(constructor().owner()); |
435 Register type_arguments = locs()->in(0).reg(); | 458 Register type_arguments = locs()->in(0).reg(); |
436 Register instantiator_type_arguments = locs()->in(1).reg(); | 459 Register instantiator_type_arguments = locs()->in(1).reg(); |
437 Register result = locs()->out().reg(); | 460 Register result = locs()->out().reg(); |
438 | 461 |
439 __ PushObject(Object::ZoneHandle()); | 462 __ PushObject(Object::ZoneHandle()); |
440 __ pushl(Immediate(Smi::RawValue(token_index()))); | 463 __ pushl(Immediate(Smi::RawValue(token_index()))); |
441 __ PushObject(cls); | 464 __ PushObject(cls); |
442 __ pushl(type_arguments); | 465 __ pushl(type_arguments); |
443 __ pushl(instantiator_type_arguments); | 466 __ pushl(instantiator_type_arguments); |
444 compiler->GenerateCallRuntime(cid(), | 467 compiler->GenerateCallRuntime(cid(), |
445 token_index(), | 468 token_index(), |
446 try_index(), | 469 try_index(), |
447 kAllocateObjectWithBoundsCheckRuntimeEntry); | 470 kAllocateObjectWithBoundsCheckRuntimeEntry); |
448 // Pop instantiator type arguments, type arguments, class, and | 471 // Pop instantiator type arguments, type arguments, class, and |
449 // source location. | 472 // source location. |
450 __ Drop(4); | 473 __ Drop(4); |
451 __ popl(result); // Pop new instance. | 474 __ popl(result); // Pop new instance. |
452 } | 475 } |
453 | 476 |
454 | 477 |
455 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { | 478 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { |
456 return LocationSummary::Make(1, Location::RequiresRegister()); | 479 return LocationSummary::Make(1, Location::RequiresRegister()); |
457 } | 480 } |
458 | 481 |
459 | 482 |
460 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 483 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
461 Register obj = locs()->in(0).reg(); | 484 Register obj = locs()->in(0).reg(); |
462 Register result = locs()->out().reg(); | 485 Register result = locs()->out().reg(); |
463 | 486 |
464 __ movl(result, FieldAddress(obj, offset_in_bytes())); | 487 __ movl(result, FieldAddress(obj, offset_in_bytes())); |
465 } | 488 } |
466 | 489 |
467 | 490 |
468 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { | 491 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { |
469 const intptr_t kNumInputs = 1; | 492 const intptr_t kNumInputs = 1; |
470 const intptr_t kNumTemps = 1; | 493 const intptr_t kNumTemps = 1; |
471 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 494 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
472 locs->set_in(0, Location::RequiresRegister()); | 495 locs->set_in(0, Location::RequiresRegister()); |
473 locs->set_temp(0, Location::RequiresRegister()); | 496 locs->set_temp(0, Location::RequiresRegister()); |
474 locs->set_out(Location::SameAsFirstInput()); | 497 locs->set_out(Location::SameAsFirstInput()); |
475 return locs; | 498 return locs; |
476 } | 499 } |
477 | 500 |
478 | 501 |
479 void InstantiateTypeArgumentsComp::EmitNativeCode( | 502 void InstantiateTypeArgumentsComp::EmitNativeCode( |
480 FlowGraphCompiler* compiler) { | 503 FlowGraphCompilerShared* compiler) { |
481 Register instantiator_reg = locs()->in(0).reg(); | 504 Register instantiator_reg = locs()->in(0).reg(); |
482 Register temp = locs()->temp(0).reg(); | 505 Register temp = locs()->temp(0).reg(); |
483 Register result_reg = locs()->out().reg(); | 506 Register result_reg = locs()->out().reg(); |
484 | 507 |
485 // 'instantiator_reg' is the instantiator AbstractTypeArguments object | 508 // 'instantiator_reg' is the instantiator AbstractTypeArguments object |
486 // (or null). | 509 // (or null). |
487 // If the instantiator is null and if the type argument vector | 510 // If the instantiator is null and if the type argument vector |
488 // instantiated from null becomes a vector of Dynamic, then use null as | 511 // instantiated from null becomes a vector of Dynamic, then use null as |
489 // the type arguments. | 512 // the type arguments. |
490 Label type_arguments_instantiated; | 513 Label type_arguments_instantiated; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 const intptr_t kNumTemps = 1; | 553 const intptr_t kNumTemps = 1; |
531 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 554 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
532 locs->set_in(0, Location::RequiresRegister()); | 555 locs->set_in(0, Location::RequiresRegister()); |
533 locs->set_out(Location::SameAsFirstInput()); | 556 locs->set_out(Location::SameAsFirstInput()); |
534 locs->set_temp(0, Location::RequiresRegister()); | 557 locs->set_temp(0, Location::RequiresRegister()); |
535 return locs; | 558 return locs; |
536 } | 559 } |
537 | 560 |
538 | 561 |
539 void ExtractConstructorTypeArgumentsComp::EmitNativeCode( | 562 void ExtractConstructorTypeArgumentsComp::EmitNativeCode( |
540 FlowGraphCompiler* compiler) { | 563 FlowGraphCompilerShared* compiler) { |
541 Register instantiator_reg = locs()->in(0).reg(); | 564 Register instantiator_reg = locs()->in(0).reg(); |
542 Register result_reg = locs()->out().reg(); | 565 Register result_reg = locs()->out().reg(); |
543 ASSERT(instantiator_reg == result_reg); | 566 ASSERT(instantiator_reg == result_reg); |
544 Register temp_reg = locs()->temp(0).reg(); | 567 Register temp_reg = locs()->temp(0).reg(); |
545 | 568 |
546 // instantiator_reg is the instantiator type argument vector, i.e. an | 569 // instantiator_reg is the instantiator type argument vector, i.e. an |
547 // AbstractTypeArguments object (or null). | 570 // AbstractTypeArguments object (or null). |
548 // If the instantiator is null and if the type argument vector | 571 // If the instantiator is null and if the type argument vector |
549 // instantiated from null becomes a vector of Dynamic, then use null as | 572 // instantiated from null becomes a vector of Dynamic, then use null as |
550 // the type arguments. | 573 // the type arguments. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 const intptr_t kNumTemps = 1; | 610 const intptr_t kNumTemps = 1; |
588 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 611 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
589 locs->set_in(0, Location::RequiresRegister()); | 612 locs->set_in(0, Location::RequiresRegister()); |
590 locs->set_out(Location::SameAsFirstInput()); | 613 locs->set_out(Location::SameAsFirstInput()); |
591 locs->set_temp(0, Location::RequiresRegister()); | 614 locs->set_temp(0, Location::RequiresRegister()); |
592 return locs; | 615 return locs; |
593 } | 616 } |
594 | 617 |
595 | 618 |
596 void ExtractConstructorInstantiatorComp::EmitNativeCode( | 619 void ExtractConstructorInstantiatorComp::EmitNativeCode( |
597 FlowGraphCompiler* compiler) { | 620 FlowGraphCompilerShared* compiler) { |
598 ASSERT(instantiator()->IsUse()); | 621 ASSERT(instantiator()->IsUse()); |
599 Register instantiator_reg = locs()->in(0).reg(); | 622 Register instantiator_reg = locs()->in(0).reg(); |
600 ASSERT(locs()->out().reg() == instantiator_reg); | 623 ASSERT(locs()->out().reg() == instantiator_reg); |
601 Register temp_reg = locs()->temp(0).reg(); | 624 Register temp_reg = locs()->temp(0).reg(); |
602 | 625 |
603 // instantiator_reg is the instantiator AbstractTypeArguments object | 626 // instantiator_reg is the instantiator AbstractTypeArguments object |
604 // (or null). If the instantiator is null and if the type argument vector | 627 // (or null). If the instantiator is null and if the type argument vector |
605 // instantiated from null becomes a vector of Dynamic, then use null as | 628 // instantiated from null becomes a vector of Dynamic, then use null as |
606 // the type arguments and do not pass the instantiator. | 629 // the type arguments and do not pass the instantiator. |
607 Label done; | 630 Label done; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
651 LocationSummary* AllocateContextComp::MakeLocationSummary() const { | 674 LocationSummary* AllocateContextComp::MakeLocationSummary() const { |
652 const intptr_t kNumInputs = 0; | 675 const intptr_t kNumInputs = 0; |
653 const intptr_t kNumTemps = 1; | 676 const intptr_t kNumTemps = 1; |
654 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 677 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
655 locs->set_temp(0, Location::RegisterLocation(EDX)); | 678 locs->set_temp(0, Location::RegisterLocation(EDX)); |
656 locs->set_out(Location::RegisterLocation(EAX)); | 679 locs->set_out(Location::RegisterLocation(EAX)); |
657 return locs; | 680 return locs; |
658 } | 681 } |
659 | 682 |
660 | 683 |
661 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 684 void AllocateContextComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
662 ASSERT(locs()->temp(0).reg() == EDX); | 685 ASSERT(locs()->temp(0).reg() == EDX); |
663 ASSERT(locs()->out().reg() == EAX); | 686 ASSERT(locs()->out().reg() == EAX); |
664 | 687 |
665 __ movl(EDX, Immediate(num_context_variables())); | 688 __ movl(EDX, Immediate(num_context_variables())); |
666 const ExternalLabel label("alloc_context", | 689 const ExternalLabel label("alloc_context", |
667 StubCode::AllocateContextEntryPoint()); | 690 StubCode::AllocateContextEntryPoint()); |
668 compiler->GenerateCall(token_index(), | 691 compiler->GenerateCall(token_index(), |
669 try_index(), | 692 try_index(), |
670 &label, | 693 &label, |
671 PcDescriptors::kOther); | 694 PcDescriptors::kOther); |
672 } | 695 } |
673 | 696 |
674 | 697 |
675 LocationSummary* CloneContextComp::MakeLocationSummary() const { | 698 LocationSummary* CloneContextComp::MakeLocationSummary() const { |
676 return LocationSummary::Make(1, Location::RequiresRegister()); | 699 return LocationSummary::Make(1, Location::RequiresRegister()); |
677 } | 700 } |
678 | 701 |
679 | 702 |
680 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 703 void CloneContextComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
681 Register context_value = locs()->in(0).reg(); | 704 Register context_value = locs()->in(0).reg(); |
682 Register result = locs()->out().reg(); | 705 Register result = locs()->out().reg(); |
683 | 706 |
684 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 707 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
685 __ pushl(context_value); | 708 __ pushl(context_value); |
686 compiler->GenerateCallRuntime(cid(), | 709 compiler->GenerateCallRuntime(cid(), |
687 token_index(), | 710 token_index(), |
688 try_index(), | 711 try_index(), |
689 kCloneContextRuntimeEntry); | 712 kCloneContextRuntimeEntry); |
690 __ popl(result); // Remove argument. | 713 __ popl(result); // Remove argument. |
691 __ popl(result); // Get result (cloned context). | 714 __ popl(result); // Get result (cloned context). |
692 } | 715 } |
693 | 716 |
694 | 717 |
695 LocationSummary* CatchEntryComp::MakeLocationSummary() const { | 718 LocationSummary* CatchEntryComp::MakeLocationSummary() const { |
696 return NULL; | 719 return LocationSummary::Make(0, Location::NoLocation()); |
697 } | 720 } |
698 | 721 |
699 | 722 |
700 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 723 // Restore stack and initialize the two exception variables: |
701 UNIMPLEMENTED(); | 724 // exception and stack trace variables. |
| 725 void CatchEntryComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
| 726 // Restore RSP from RBP as we are coming from a throw and the code for |
| 727 // popping arguments has not been run. |
| 728 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; |
| 729 ASSERT(locals_space_size >= 0); |
| 730 const intptr_t offset_size = |
| 731 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; |
| 732 __ leal(ESP, Address(EBP, offset_size)); |
| 733 |
| 734 ASSERT(!exception_var().is_captured()); |
| 735 ASSERT(!stacktrace_var().is_captured()); |
| 736 __ movl(Address(EBP, exception_var().index() * kWordSize), |
| 737 kExceptionObjectReg); |
| 738 __ movl(Address(EBP, stacktrace_var().index() * kWordSize), |
| 739 kStackTraceObjectReg); |
702 } | 740 } |
703 | 741 |
704 | 742 |
705 LocationSummary* BinaryOpComp::MakeLocationSummary() const { | 743 LocationSummary* BinaryOpComp::MakeLocationSummary() const { |
706 const intptr_t kNumInputs = 2; | 744 const intptr_t kNumInputs = 2; |
707 const intptr_t kNumTemps = 0; | 745 const intptr_t kNumTemps = 0; |
708 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 746 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
709 summary->set_in(0, Location::RequiresRegister()); | 747 summary->set_in(0, Location::RequiresRegister()); |
710 summary->set_in(1, Location::RequiresRegister()); | 748 summary->set_in(1, Location::RequiresRegister()); |
711 summary->set_out(Location::SameAsFirstInput()); | 749 summary->set_out(Location::SameAsFirstInput()); |
712 return summary; | 750 return summary; |
713 } | 751 } |
714 | 752 |
715 | 753 |
716 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 754 void BinaryOpComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
717 // TODO(srdjan): Remove this code once BinaryOpComp has been implemeneted | 755 // TODO(srdjan): Remove this code once BinaryOpComp has been implemeneted |
718 // for all intended operations. | 756 // for all intended operations. |
719 Register left = locs()->in(0).reg(); | 757 Register left = locs()->in(0).reg(); |
720 Register right = locs()->in(1).reg(); | 758 Register right = locs()->in(1).reg(); |
721 __ pushl(left); | 759 __ pushl(left); |
722 __ pushl(right); | 760 __ pushl(right); |
723 InstanceCallComp* instance_call_comp = instance_call(); | 761 InstanceCallComp* instance_call_comp = instance_call(); |
724 instance_call_comp->EmitNativeCode(compiler); | 762 instance_call_comp->EmitNativeCode(compiler); |
725 if (locs()->out().reg() != EAX) { | 763 if (locs()->out().reg() != EAX) { |
726 __ movl(locs()->out().reg(), EAX); | 764 __ movl(locs()->out().reg(), EAX); |
727 } | 765 } |
728 } | 766 } |
729 | 767 |
730 | 768 |
731 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { | 769 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { |
732 const intptr_t kNumInputs = 1; | 770 const intptr_t kNumInputs = 1; |
733 const intptr_t kNumTemps = 0; | 771 const intptr_t kNumTemps = 0; |
734 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 772 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
735 summary->set_in(0, Location::RequiresRegister()); | 773 summary->set_in(0, Location::RequiresRegister()); |
736 summary->set_out(Location::SameAsFirstInput()); | 774 summary->set_out(Location::SameAsFirstInput()); |
737 return summary; | 775 return summary; |
738 } | 776 } |
739 | 777 |
740 | 778 |
741 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 779 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
742 const ICData& ic_data = *instance_call()->ic_data(); | 780 const ICData& ic_data = *instance_call()->ic_data(); |
743 ASSERT(!ic_data.IsNull()); | 781 ASSERT(!ic_data.IsNull()); |
744 ASSERT(ic_data.num_args_tested() == 1); | 782 ASSERT(ic_data.num_args_tested() == 1); |
745 // TODO(srdjan): Implement for more checks. | 783 // TODO(srdjan): Implement for more checks. |
746 ASSERT(ic_data.NumberOfChecks() == 1); | 784 ASSERT(ic_data.NumberOfChecks() == 1); |
747 Class& test_class = Class::Handle(); | 785 Class& test_class = Class::Handle(); |
748 Function& target = Function::Handle(); | 786 Function& target = Function::Handle(); |
749 ic_data.GetOneClassCheckAt(0, &test_class, &target); | 787 ic_data.GetOneClassCheckAt(0, &test_class, &target); |
750 | 788 |
751 Register value = locs()->in(0).reg(); | 789 Register value = locs()->in(0).reg(); |
(...skipping 30 matching lines...) Expand all Loading... |
782 const intptr_t kNumInputs = 1; | 820 const intptr_t kNumInputs = 1; |
783 const intptr_t kNumTemps = 1; // Needed for doubles. | 821 const intptr_t kNumTemps = 1; // Needed for doubles. |
784 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 822 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
785 summary->set_in(0, Location::RequiresRegister()); | 823 summary->set_in(0, Location::RequiresRegister()); |
786 summary->set_out(Location::SameAsFirstInput()); | 824 summary->set_out(Location::SameAsFirstInput()); |
787 summary->set_temp(0, Location::RequiresRegister()); | 825 summary->set_temp(0, Location::RequiresRegister()); |
788 return summary; | 826 return summary; |
789 } | 827 } |
790 | 828 |
791 | 829 |
792 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 830 void NumberNegateComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
793 const ICData& ic_data = *instance_call()->ic_data(); | 831 const ICData& ic_data = *instance_call()->ic_data(); |
794 ASSERT(!ic_data.IsNull()); | 832 ASSERT(!ic_data.IsNull()); |
795 ASSERT(ic_data.num_args_tested() == 1); | 833 ASSERT(ic_data.num_args_tested() == 1); |
796 | 834 |
797 // TODO(srdjan): Implement for more checks. | 835 // TODO(srdjan): Implement for more checks. |
798 ASSERT(ic_data.NumberOfChecks() == 1); | 836 ASSERT(ic_data.NumberOfChecks() == 1); |
799 Class& test_class = Class::Handle(); | 837 Class& test_class = Class::Handle(); |
800 Function& target = Function::Handle(); | 838 Function& target = Function::Handle(); |
801 ic_data.GetOneClassCheckAt(0, &test_class, &target); | 839 ic_data.GetOneClassCheckAt(0, &test_class, &target); |
802 | 840 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 UNREACHABLE(); | 875 UNREACHABLE(); |
838 } | 876 } |
839 } | 877 } |
840 | 878 |
841 | 879 |
842 } // namespace dart | 880 } // namespace dart |
843 | 881 |
844 #undef __ | 882 #undef __ |
845 | 883 |
846 #endif // defined TARGET_ARCH_X64 | 884 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |