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

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

Issue 10538024: Implemented missing instructions in ia32, more sharing, removed bailouts, enable optimiziations on … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698