OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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 <setjmp.h> // NOLINT | 5 #include <setjmp.h> // NOLINT |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 | 7 |
8 #include "vm/globals.h" | 8 #include "vm/globals.h" |
9 #if defined(TARGET_ARCH_DBC) | 9 #if defined(TARGET_ARCH_DBC) |
10 | 10 |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "vm/native_arguments.h" | 25 #include "vm/native_arguments.h" |
26 #include "vm/native_entry.h" | 26 #include "vm/native_entry.h" |
27 #include "vm/object.h" | 27 #include "vm/object.h" |
28 #include "vm/object_store.h" | 28 #include "vm/object_store.h" |
29 #include "vm/os_thread.h" | 29 #include "vm/os_thread.h" |
30 #include "vm/stack_frame.h" | 30 #include "vm/stack_frame.h" |
31 #include "vm/symbols.h" | 31 #include "vm/symbols.h" |
32 | 32 |
33 namespace dart { | 33 namespace dart { |
34 | 34 |
35 DEFINE_FLAG(uint64_t, trace_sim_after, ULLONG_MAX, | 35 DEFINE_FLAG(uint64_t, |
| 36 trace_sim_after, |
| 37 ULLONG_MAX, |
36 "Trace simulator execution after instruction count reached."); | 38 "Trace simulator execution after instruction count reached."); |
37 DEFINE_FLAG(uint64_t, stop_sim_at, ULLONG_MAX, | 39 DEFINE_FLAG(uint64_t, |
| 40 stop_sim_at, |
| 41 ULLONG_MAX, |
38 "Instruction address or instruction count to stop simulator at."); | 42 "Instruction address or instruction count to stop simulator at."); |
39 | 43 |
40 #define LIKELY(cond) __builtin_expect((cond), 1) | 44 #define LIKELY(cond) __builtin_expect((cond), 1) |
41 #define UNLIKELY(cond) __builtin_expect((cond), 0) | 45 #define UNLIKELY(cond) __builtin_expect((cond), 0) |
42 | 46 |
43 // SimulatorSetjmpBuffer are linked together, and the last created one | 47 // SimulatorSetjmpBuffer are linked together, and the last created one |
44 // is referenced by the Simulator. When an exception is thrown, the exception | 48 // is referenced by the Simulator. When an exception is thrown, the exception |
45 // runtime looks at where to jump and finds the corresponding | 49 // runtime looks at where to jump and finds the corresponding |
46 // SimulatorSetjmpBuffer based on the stack pointer of the exception handler. | 50 // SimulatorSetjmpBuffer based on the stack pointer of the exception handler. |
47 // The runtime then does a Longjmp on that buffer to return to the simulator. | 51 // The runtime then does a Longjmp on that buffer to return to the simulator. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 return reinterpret_cast<RawObject**>(FP[kSavedCallerFpSlotFromFp]); | 94 return reinterpret_cast<RawObject**>(FP[kSavedCallerFpSlotFromFp]); |
91 } | 95 } |
92 | 96 |
93 | 97 |
94 DART_FORCE_INLINE static RawObject** FrameArguments(RawObject** FP, | 98 DART_FORCE_INLINE static RawObject** FrameArguments(RawObject** FP, |
95 intptr_t argc) { | 99 intptr_t argc) { |
96 return FP - (kDartFrameFixedSize + argc); | 100 return FP - (kDartFrameFixedSize + argc); |
97 } | 101 } |
98 | 102 |
99 | 103 |
100 #define RAW_CAST(Type, val) (SimulatorHelpers::CastTo##Type(val)) | 104 #define RAW_CAST(Type, val) (SimulatorHelpers::CastTo##Type(val)) |
101 | 105 |
102 | 106 |
103 class SimulatorHelpers { | 107 class SimulatorHelpers { |
104 public: | 108 public: |
105 #define DEFINE_CASTS(Type) \ | 109 #define DEFINE_CASTS(Type) \ |
106 DART_FORCE_INLINE static Raw##Type* CastTo##Type(RawObject* obj) { \ | 110 DART_FORCE_INLINE static Raw##Type* CastTo##Type(RawObject* obj) { \ |
107 ASSERT((k##Type##Cid == kSmiCid) ? !obj->IsHeapObject() \ | 111 ASSERT((k##Type##Cid == kSmiCid) ? !obj->IsHeapObject() \ |
108 : obj->Is##Type()); \ | 112 : obj->Is##Type()); \ |
109 return reinterpret_cast<Raw##Type*>(obj); \ | 113 return reinterpret_cast<Raw##Type*>(obj); \ |
110 } | 114 } |
111 CLASS_LIST(DEFINE_CASTS) | 115 CLASS_LIST(DEFINE_CASTS) |
112 #undef DEFINE_CASTS | 116 #undef DEFINE_CASTS |
113 | 117 |
114 DART_FORCE_INLINE static RawSmi* GetClassIdAsSmi(RawObject* obj) { | 118 DART_FORCE_INLINE static RawSmi* GetClassIdAsSmi(RawObject* obj) { |
115 return Smi::New(obj->IsHeapObject() ? obj->GetClassId() | 119 return Smi::New(obj->IsHeapObject() ? obj->GetClassId() |
116 : static_cast<intptr_t>(kSmiCid)); | 120 : static_cast<intptr_t>(kSmiCid)); |
117 } | 121 } |
118 | 122 |
119 DART_FORCE_INLINE static intptr_t GetClassId(RawObject* obj) { | 123 DART_FORCE_INLINE static intptr_t GetClassId(RawObject* obj) { |
120 return obj->IsHeapObject() ? obj->GetClassId() | 124 return obj->IsHeapObject() ? obj->GetClassId() |
121 : static_cast<intptr_t>(kSmiCid); | 125 : static_cast<intptr_t>(kSmiCid); |
122 } | 126 } |
123 | 127 |
124 DART_FORCE_INLINE static void IncrementUsageCounter(RawFunction* f) { | 128 DART_FORCE_INLINE static void IncrementUsageCounter(RawFunction* f) { |
125 f->ptr()->usage_counter_++; | 129 f->ptr()->usage_counter_++; |
126 } | 130 } |
127 | 131 |
128 DART_FORCE_INLINE static void IncrementICUsageCount(RawObject** entries, | 132 DART_FORCE_INLINE static void IncrementICUsageCount(RawObject** entries, |
129 intptr_t offset, | 133 intptr_t offset, |
130 intptr_t args_tested) { | 134 intptr_t args_tested) { |
131 const intptr_t count_offset = ICData::CountIndexFor(args_tested); | 135 const intptr_t count_offset = ICData::CountIndexFor(args_tested); |
132 const intptr_t raw_smi_old = | 136 const intptr_t raw_smi_old = |
133 reinterpret_cast<intptr_t>(entries[offset + count_offset]); | 137 reinterpret_cast<intptr_t>(entries[offset + count_offset]); |
134 const intptr_t raw_smi_new = raw_smi_old + Smi::RawValue(1); | 138 const intptr_t raw_smi_new = raw_smi_old + Smi::RawValue(1); |
135 *reinterpret_cast<intptr_t*>(&entries[offset + count_offset]) = | 139 *reinterpret_cast<intptr_t*>(&entries[offset + count_offset]) = raw_smi_new; |
136 raw_smi_new; | |
137 } | 140 } |
138 | 141 |
139 DART_FORCE_INLINE static bool IsStrictEqualWithNumberCheck(RawObject* lhs, | 142 DART_FORCE_INLINE static bool IsStrictEqualWithNumberCheck(RawObject* lhs, |
140 RawObject* rhs) { | 143 RawObject* rhs) { |
141 if (lhs == rhs) { | 144 if (lhs == rhs) { |
142 return true; | 145 return true; |
143 } | 146 } |
144 | 147 |
145 if (lhs->IsHeapObject() && rhs->IsHeapObject()) { | 148 if (lhs->IsHeapObject() && rhs->IsHeapObject()) { |
146 const intptr_t lhs_cid = lhs->GetClassId(); | 149 const intptr_t lhs_cid = lhs->GetClassId(); |
(...skipping 19 matching lines...) Expand all Loading... |
166 | 169 |
167 return false; | 170 return false; |
168 } | 171 } |
169 | 172 |
170 template <typename T> | 173 template <typename T> |
171 DART_FORCE_INLINE static T* Untag(T* tagged) { | 174 DART_FORCE_INLINE static T* Untag(T* tagged) { |
172 return tagged->ptr(); | 175 return tagged->ptr(); |
173 } | 176 } |
174 | 177 |
175 DART_FORCE_INLINE static bool CheckIndex(RawSmi* index, RawSmi* length) { | 178 DART_FORCE_INLINE static bool CheckIndex(RawSmi* index, RawSmi* length) { |
176 return !index->IsHeapObject() && | 179 return !index->IsHeapObject() && (reinterpret_cast<intptr_t>(index) >= 0) && |
177 (reinterpret_cast<intptr_t>(index) >= 0) && | |
178 (reinterpret_cast<intptr_t>(index) < | 180 (reinterpret_cast<intptr_t>(index) < |
179 reinterpret_cast<intptr_t>(length)); | 181 reinterpret_cast<intptr_t>(length)); |
180 } | 182 } |
181 | 183 |
182 static bool ObjectArraySetIndexed(Thread* thread, | 184 static bool ObjectArraySetIndexed(Thread* thread, |
183 RawObject** FP, | 185 RawObject** FP, |
184 RawObject** result) { | 186 RawObject** result) { |
185 if (thread->isolate()->type_checks()) { | 187 if (thread->isolate()->type_checks()) { |
186 return false; | 188 return false; |
187 } | 189 } |
188 | 190 |
189 RawObject** args = FrameArguments(FP, 3); | 191 RawObject** args = FrameArguments(FP, 3); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 return true; | 242 return true; |
241 } | 243 } |
242 return false; | 244 return false; |
243 } | 245 } |
244 | 246 |
245 static bool Double_getIsNan(Thread* thread, | 247 static bool Double_getIsNan(Thread* thread, |
246 RawObject** FP, | 248 RawObject** FP, |
247 RawObject** result) { | 249 RawObject** result) { |
248 RawObject** args = FrameArguments(FP, 1); | 250 RawObject** args = FrameArguments(FP, 1); |
249 RawDouble* d = static_cast<RawDouble*>(args[0]); | 251 RawDouble* d = static_cast<RawDouble*>(args[0]); |
250 *result = isnan(d->ptr()->value_) | 252 *result = |
251 ? Bool::True().raw() | 253 isnan(d->ptr()->value_) ? Bool::True().raw() : Bool::False().raw(); |
252 : Bool::False().raw(); | |
253 return true; | 254 return true; |
254 } | 255 } |
255 | 256 |
256 static bool Double_getIsInfinite(Thread* thread, | 257 static bool Double_getIsInfinite(Thread* thread, |
257 RawObject** FP, | 258 RawObject** FP, |
258 RawObject** result) { | 259 RawObject** result) { |
259 RawObject** args = FrameArguments(FP, 1); | 260 RawObject** args = FrameArguments(FP, 1); |
260 RawDouble* d = static_cast<RawDouble*>(args[0]); | 261 RawDouble* d = static_cast<RawDouble*>(args[0]); |
261 *result = isinf(d->ptr()->value_) | 262 *result = |
262 ? Bool::True().raw() | 263 isinf(d->ptr()->value_) ? Bool::True().raw() : Bool::False().raw(); |
263 : Bool::False().raw(); | |
264 return true; | 264 return true; |
265 } | 265 } |
266 | 266 |
267 static bool ObjectEquals(Thread* thread, | 267 static bool ObjectEquals(Thread* thread, RawObject** FP, RawObject** result) { |
268 RawObject** FP, | |
269 RawObject** result) { | |
270 RawObject** args = FrameArguments(FP, 2); | 268 RawObject** args = FrameArguments(FP, 2); |
271 *result = args[0] == args[1] ? Bool::True().raw() : Bool::False().raw(); | 269 *result = args[0] == args[1] ? Bool::True().raw() : Bool::False().raw(); |
272 return true; | 270 return true; |
273 } | 271 } |
274 | 272 |
275 static bool ObjectRuntimeType(Thread* thread, | 273 static bool ObjectRuntimeType(Thread* thread, |
276 RawObject** FP, | 274 RawObject** FP, |
277 RawObject** result) { | 275 RawObject** result) { |
278 RawObject** args = FrameArguments(FP, 1); | 276 RawObject** args = FrameArguments(FP, 1); |
279 const intptr_t cid = GetClassId(args[0]); | 277 const intptr_t cid = GetClassId(args[0]); |
(...skipping 20 matching lines...) Expand all Loading... |
300 if (typ == Object::null()) { | 298 if (typ == Object::null()) { |
301 return false; | 299 return false; |
302 } | 300 } |
303 *result = static_cast<RawObject*>(typ); | 301 *result = static_cast<RawObject*>(typ); |
304 return true; | 302 return true; |
305 } | 303 } |
306 | 304 |
307 static bool GetDoubleOperands(RawObject** args, double* d1, double* d2) { | 305 static bool GetDoubleOperands(RawObject** args, double* d1, double* d2) { |
308 RawObject* obj2 = args[1]; | 306 RawObject* obj2 = args[1]; |
309 if (!obj2->IsHeapObject()) { | 307 if (!obj2->IsHeapObject()) { |
310 *d2 = static_cast<double>( | 308 *d2 = |
311 reinterpret_cast<intptr_t>(obj2) >> kSmiTagSize); | 309 static_cast<double>(reinterpret_cast<intptr_t>(obj2) >> kSmiTagSize); |
312 } else if (obj2->GetClassId() == kDoubleCid) { | 310 } else if (obj2->GetClassId() == kDoubleCid) { |
313 RawDouble* obj2d = static_cast<RawDouble*>(obj2); | 311 RawDouble* obj2d = static_cast<RawDouble*>(obj2); |
314 *d2 = obj2d->ptr()->value_; | 312 *d2 = obj2d->ptr()->value_; |
315 } else { | 313 } else { |
316 return false; | 314 return false; |
317 } | 315 } |
318 RawDouble* obj1 = static_cast<RawDouble*>(args[0]); | 316 RawDouble* obj1 = static_cast<RawDouble*>(args[0]); |
319 *d1 = obj1->ptr()->value_; | 317 *d1 = obj1->ptr()->value_; |
320 return true; | 318 return true; |
321 } | 319 } |
322 | 320 |
323 static RawObject* AllocateDouble(Thread* thread, double value) { | 321 static RawObject* AllocateDouble(Thread* thread, double value) { |
324 const intptr_t instance_size = Double::InstanceSize(); | 322 const intptr_t instance_size = Double::InstanceSize(); |
325 const uword start = | 323 const uword start = thread->heap()->new_space()->TryAllocate(instance_size); |
326 thread->heap()->new_space()->TryAllocate(instance_size); | |
327 if (LIKELY(start != 0)) { | 324 if (LIKELY(start != 0)) { |
328 uword tags = 0; | 325 uword tags = 0; |
329 tags = RawObject::ClassIdTag::update(kDoubleCid, tags); | 326 tags = RawObject::ClassIdTag::update(kDoubleCid, tags); |
330 tags = RawObject::SizeTag::update(instance_size, tags); | 327 tags = RawObject::SizeTag::update(instance_size, tags); |
331 *reinterpret_cast<uword*>(start + Double::tags_offset()) = tags; | 328 *reinterpret_cast<uword*>(start + Double::tags_offset()) = tags; |
332 *reinterpret_cast<double*>(start + Double::value_offset()) = value; | 329 *reinterpret_cast<double*>(start + Double::value_offset()) = value; |
333 return reinterpret_cast<RawObject*>(start + kHeapObjectTag); | 330 return reinterpret_cast<RawObject*>(start + kHeapObjectTag); |
334 } | 331 } |
335 return NULL; | 332 return NULL; |
336 } | 333 } |
337 | 334 |
338 static bool Double_add(Thread* thread, | 335 static bool Double_add(Thread* thread, RawObject** FP, RawObject** result) { |
339 RawObject** FP, | |
340 RawObject** result) { | |
341 double d1, d2; | 336 double d1, d2; |
342 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { | 337 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { |
343 return false; | 338 return false; |
344 } | 339 } |
345 RawObject* new_double = AllocateDouble(thread, d1 + d2); | 340 RawObject* new_double = AllocateDouble(thread, d1 + d2); |
346 if (new_double != NULL) { | 341 if (new_double != NULL) { |
347 *result = new_double; | 342 *result = new_double; |
348 return true; | 343 return true; |
349 } | 344 } |
350 return false; | 345 return false; |
351 } | 346 } |
352 | 347 |
353 static bool Double_mul(Thread* thread, | 348 static bool Double_mul(Thread* thread, RawObject** FP, RawObject** result) { |
354 RawObject** FP, | |
355 RawObject** result) { | |
356 double d1, d2; | 349 double d1, d2; |
357 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { | 350 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { |
358 return false; | 351 return false; |
359 } | 352 } |
360 RawObject* new_double = AllocateDouble(thread, d1 * d2); | 353 RawObject* new_double = AllocateDouble(thread, d1 * d2); |
361 if (new_double != NULL) { | 354 if (new_double != NULL) { |
362 *result = new_double; | 355 *result = new_double; |
363 return true; | 356 return true; |
364 } | 357 } |
365 return false; | 358 return false; |
366 } | 359 } |
367 | 360 |
368 static bool Double_sub(Thread* thread, | 361 static bool Double_sub(Thread* thread, RawObject** FP, RawObject** result) { |
369 RawObject** FP, | |
370 RawObject** result) { | |
371 double d1, d2; | 362 double d1, d2; |
372 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { | 363 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { |
373 return false; | 364 return false; |
374 } | 365 } |
375 RawObject* new_double = AllocateDouble(thread, d1 - d2); | 366 RawObject* new_double = AllocateDouble(thread, d1 - d2); |
376 if (new_double != NULL) { | 367 if (new_double != NULL) { |
377 *result = new_double; | 368 *result = new_double; |
378 return true; | 369 return true; |
379 } | 370 } |
380 return false; | 371 return false; |
381 } | 372 } |
382 | 373 |
383 static bool Double_div(Thread* thread, | 374 static bool Double_div(Thread* thread, RawObject** FP, RawObject** result) { |
384 RawObject** FP, | |
385 RawObject** result) { | |
386 double d1, d2; | 375 double d1, d2; |
387 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { | 376 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { |
388 return false; | 377 return false; |
389 } | 378 } |
390 RawObject* new_double = AllocateDouble(thread, d1 / d2); | 379 RawObject* new_double = AllocateDouble(thread, d1 / d2); |
391 if (new_double != NULL) { | 380 if (new_double != NULL) { |
392 *result = new_double; | 381 *result = new_double; |
393 return true; | 382 return true; |
394 } | 383 } |
395 return false; | 384 return false; |
396 } | 385 } |
397 | 386 |
398 static bool Double_greaterThan(Thread* thread, | 387 static bool Double_greaterThan(Thread* thread, |
399 RawObject** FP, | 388 RawObject** FP, |
400 RawObject** result) { | 389 RawObject** result) { |
401 double d1, d2; | 390 double d1, d2; |
402 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { | 391 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { |
403 return false; | 392 return false; |
404 } | 393 } |
405 *result = d1 > d2 ? Bool::True().raw() : Bool::False().raw(); | 394 *result = d1 > d2 ? Bool::True().raw() : Bool::False().raw(); |
406 return true; | 395 return true; |
407 } | 396 } |
408 | 397 |
409 static bool Double_greaterEqualThan(Thread* thread, | 398 static bool Double_greaterEqualThan(Thread* thread, |
410 RawObject** FP, | 399 RawObject** FP, |
411 RawObject** result) { | 400 RawObject** result) { |
412 double d1, d2; | 401 double d1, d2; |
413 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { | 402 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { |
414 return false; | 403 return false; |
415 } | 404 } |
416 *result = d1 >= d2 ? Bool::True().raw() : Bool::False().raw(); | 405 *result = d1 >= d2 ? Bool::True().raw() : Bool::False().raw(); |
417 return true; | 406 return true; |
418 } | 407 } |
419 | 408 |
420 static bool Double_lessThan(Thread* thread, | 409 static bool Double_lessThan(Thread* thread, |
421 RawObject** FP, | 410 RawObject** FP, |
422 RawObject** result) { | 411 RawObject** result) { |
423 double d1, d2; | 412 double d1, d2; |
424 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { | 413 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { |
425 return false; | 414 return false; |
426 } | 415 } |
427 *result = d1 < d2 ? Bool::True().raw() : Bool::False().raw(); | 416 *result = d1 < d2 ? Bool::True().raw() : Bool::False().raw(); |
428 return true; | 417 return true; |
429 } | 418 } |
430 | 419 |
431 static bool Double_equal(Thread* thread, | 420 static bool Double_equal(Thread* thread, RawObject** FP, RawObject** result) { |
432 RawObject** FP, | |
433 RawObject** result) { | |
434 double d1, d2; | 421 double d1, d2; |
435 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { | 422 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { |
436 return false; | 423 return false; |
437 } | 424 } |
438 *result = d1 == d2 ? Bool::True().raw() : Bool::False().raw(); | 425 *result = d1 == d2 ? Bool::True().raw() : Bool::False().raw(); |
439 return true; | 426 return true; |
440 } | 427 } |
441 | 428 |
442 static bool Double_lessEqualThan(Thread* thread, | 429 static bool Double_lessEqualThan(Thread* thread, |
443 RawObject** FP, | 430 RawObject** FP, |
444 RawObject** result) { | 431 RawObject** result) { |
445 double d1, d2; | 432 double d1, d2; |
446 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { | 433 if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) { |
447 return false; | 434 return false; |
448 } | 435 } |
449 *result = d1 <= d2 ? Bool::True().raw() : Bool::False().raw(); | 436 *result = d1 <= d2 ? Bool::True().raw() : Bool::False().raw(); |
450 return true; | 437 return true; |
451 } | 438 } |
452 | 439 |
453 DART_FORCE_INLINE static RawCode* FrameCode(RawObject** FP) { | 440 DART_FORCE_INLINE static RawCode* FrameCode(RawObject** FP) { |
454 ASSERT(GetClassId(FP[kPcMarkerSlotFromFp]) == kCodeCid); | 441 ASSERT(GetClassId(FP[kPcMarkerSlotFromFp]) == kCodeCid); |
455 return static_cast<RawCode*>(FP[kPcMarkerSlotFromFp]); | 442 return static_cast<RawCode*>(FP[kPcMarkerSlotFromFp]); |
456 } | 443 } |
457 | 444 |
458 | 445 |
459 DART_FORCE_INLINE static void SetFrameCode(RawObject** FP, RawCode* code) { | 446 DART_FORCE_INLINE static void SetFrameCode(RawObject** FP, RawCode* code) { |
460 ASSERT(GetClassId(code) == kCodeCid); | 447 ASSERT(GetClassId(code) == kCodeCid); |
461 FP[kPcMarkerSlotFromFp] = code; | 448 FP[kPcMarkerSlotFromFp] = code; |
462 } | 449 } |
463 | 450 |
464 DART_FORCE_INLINE static uint8_t* GetTypedData( | 451 DART_FORCE_INLINE static uint8_t* GetTypedData(RawObject* obj, |
465 RawObject* obj, RawObject* index) { | 452 RawObject* index) { |
466 ASSERT(RawObject::IsTypedDataClassId(obj->GetClassId())); | 453 ASSERT(RawObject::IsTypedDataClassId(obj->GetClassId())); |
467 RawTypedData* array = reinterpret_cast<RawTypedData*>(obj); | 454 RawTypedData* array = reinterpret_cast<RawTypedData*>(obj); |
468 const intptr_t byte_offset = Smi::Value(RAW_CAST(Smi, index)); | 455 const intptr_t byte_offset = Smi::Value(RAW_CAST(Smi, index)); |
469 ASSERT(byte_offset >= 0); | 456 ASSERT(byte_offset >= 0); |
470 return array->ptr()->data() + byte_offset; | 457 return array->ptr()->data() + byte_offset; |
471 } | 458 } |
472 }; | 459 }; |
473 | 460 |
474 | 461 |
475 DART_FORCE_INLINE static uint32_t* SavedCallerPC(RawObject** FP) { | 462 DART_FORCE_INLINE static uint32_t* SavedCallerPC(RawObject** FP) { |
(...skipping 18 matching lines...) Expand all Loading... |
494 } | 481 } |
495 | 482 |
496 intrinsics_[kObjectArraySetIndexedIntrinsic] = | 483 intrinsics_[kObjectArraySetIndexedIntrinsic] = |
497 SimulatorHelpers::ObjectArraySetIndexed; | 484 SimulatorHelpers::ObjectArraySetIndexed; |
498 intrinsics_[kObjectArrayGetIndexedIntrinsic] = | 485 intrinsics_[kObjectArrayGetIndexedIntrinsic] = |
499 SimulatorHelpers::ObjectArrayGetIndexed; | 486 SimulatorHelpers::ObjectArrayGetIndexed; |
500 intrinsics_[kGrowableArraySetIndexedIntrinsic] = | 487 intrinsics_[kGrowableArraySetIndexedIntrinsic] = |
501 SimulatorHelpers::GrowableArraySetIndexed; | 488 SimulatorHelpers::GrowableArraySetIndexed; |
502 intrinsics_[kGrowableArrayGetIndexedIntrinsic] = | 489 intrinsics_[kGrowableArrayGetIndexedIntrinsic] = |
503 SimulatorHelpers::GrowableArrayGetIndexed; | 490 SimulatorHelpers::GrowableArrayGetIndexed; |
504 intrinsics_[kObjectEqualsIntrinsic] = | 491 intrinsics_[kObjectEqualsIntrinsic] = SimulatorHelpers::ObjectEquals; |
505 SimulatorHelpers::ObjectEquals; | |
506 intrinsics_[kObjectRuntimeTypeIntrinsic] = | 492 intrinsics_[kObjectRuntimeTypeIntrinsic] = |
507 SimulatorHelpers::ObjectRuntimeType; | 493 SimulatorHelpers::ObjectRuntimeType; |
508 | 494 |
509 intrinsics_[kDouble_getIsNaNIntrinsic] = | 495 intrinsics_[kDouble_getIsNaNIntrinsic] = SimulatorHelpers::Double_getIsNan; |
510 SimulatorHelpers::Double_getIsNan; | |
511 intrinsics_[kDouble_getIsInfiniteIntrinsic] = | 496 intrinsics_[kDouble_getIsInfiniteIntrinsic] = |
512 SimulatorHelpers::Double_getIsInfinite; | 497 SimulatorHelpers::Double_getIsInfinite; |
513 intrinsics_[kDouble_addIntrinsic] = | 498 intrinsics_[kDouble_addIntrinsic] = SimulatorHelpers::Double_add; |
514 SimulatorHelpers::Double_add; | 499 intrinsics_[kDouble_mulIntrinsic] = SimulatorHelpers::Double_mul; |
515 intrinsics_[kDouble_mulIntrinsic] = | 500 intrinsics_[kDouble_subIntrinsic] = SimulatorHelpers::Double_sub; |
516 SimulatorHelpers::Double_mul; | 501 intrinsics_[kDouble_divIntrinsic] = SimulatorHelpers::Double_div; |
517 intrinsics_[kDouble_subIntrinsic] = | |
518 SimulatorHelpers::Double_sub; | |
519 intrinsics_[kDouble_divIntrinsic] = | |
520 SimulatorHelpers::Double_div; | |
521 intrinsics_[kDouble_greaterThanIntrinsic] = | 502 intrinsics_[kDouble_greaterThanIntrinsic] = |
522 SimulatorHelpers::Double_greaterThan; | 503 SimulatorHelpers::Double_greaterThan; |
523 intrinsics_[kDouble_greaterEqualThanIntrinsic] = | 504 intrinsics_[kDouble_greaterEqualThanIntrinsic] = |
524 SimulatorHelpers::Double_greaterEqualThan; | 505 SimulatorHelpers::Double_greaterEqualThan; |
525 intrinsics_[kDouble_lessThanIntrinsic] = | 506 intrinsics_[kDouble_lessThanIntrinsic] = SimulatorHelpers::Double_lessThan; |
526 SimulatorHelpers::Double_lessThan; | 507 intrinsics_[kDouble_equalIntrinsic] = SimulatorHelpers::Double_equal; |
527 intrinsics_[kDouble_equalIntrinsic] = | |
528 SimulatorHelpers::Double_equal; | |
529 intrinsics_[kDouble_lessEqualThanIntrinsic] = | 508 intrinsics_[kDouble_lessEqualThanIntrinsic] = |
530 SimulatorHelpers::Double_lessEqualThan; | 509 SimulatorHelpers::Double_lessEqualThan; |
531 } | 510 } |
532 | 511 |
533 | 512 |
534 Simulator::Simulator() | 513 Simulator::Simulator() : stack_(NULL), fp_(NULL), sp_(NULL) { |
535 : stack_(NULL), | |
536 fp_(NULL), | |
537 sp_(NULL) { | |
538 // Setup simulator support first. Some of this information is needed to | 514 // Setup simulator support first. Some of this information is needed to |
539 // setup the architecture state. | 515 // setup the architecture state. |
540 // We allocate the stack here, the size is computed as the sum of | 516 // We allocate the stack here, the size is computed as the sum of |
541 // the size specified by the user and the buffer space needed for | 517 // the size specified by the user and the buffer space needed for |
542 // handling stack overflow exceptions. To be safe in potential | 518 // handling stack overflow exceptions. To be safe in potential |
543 // stack underflows we also add some underflow buffer space. | 519 // stack underflows we also add some underflow buffer space. |
544 stack_ = new uintptr_t[(OSThread::GetSpecifiedStackSize() + | 520 stack_ = new uintptr_t[(OSThread::GetSpecifiedStackSize() + |
545 OSThread::kStackSizeBuffer + | 521 OSThread::kStackSizeBuffer + |
546 kSimulatorStackUnderflowSize) / | 522 kSimulatorStackUnderflowSize) / |
547 sizeof(uintptr_t)]; | 523 sizeof(uintptr_t)]; |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 return (res != 0); | 695 return (res != 0); |
720 } | 696 } |
721 | 697 |
722 | 698 |
723 DART_FORCE_INLINE static bool AreBothSmis(intptr_t a, intptr_t b) { | 699 DART_FORCE_INLINE static bool AreBothSmis(intptr_t a, intptr_t b) { |
724 return ((a | b) & kHeapObjectTag) == 0; | 700 return ((a | b) & kHeapObjectTag) == 0; |
725 } | 701 } |
726 | 702 |
727 | 703 |
728 #define SMI_MUL(lhs, rhs, pres) SignedMulWithOverflow((lhs), (rhs) >> 1, pres) | 704 #define SMI_MUL(lhs, rhs, pres) SignedMulWithOverflow((lhs), (rhs) >> 1, pres) |
729 #define SMI_COND(cond, lhs, rhs, pres) \ | 705 #define SMI_COND(cond, lhs, rhs, pres) \ |
730 ((*(pres) = ((lhs cond rhs) ? true_value : false_value)), false) | 706 ((*(pres) = ((lhs cond rhs) ? true_value : false_value)), false) |
731 #define SMI_EQ(lhs, rhs, pres) SMI_COND(==, lhs, rhs, pres) | 707 #define SMI_EQ(lhs, rhs, pres) SMI_COND(==, lhs, rhs, pres) |
732 #define SMI_LT(lhs, rhs, pres) SMI_COND(<, lhs, rhs, pres) | 708 #define SMI_LT(lhs, rhs, pres) SMI_COND(<, lhs, rhs, pres) |
733 #define SMI_GT(lhs, rhs, pres) SMI_COND(>, lhs, rhs, pres) | 709 #define SMI_GT(lhs, rhs, pres) SMI_COND(>, lhs, rhs, pres) |
734 #define SMI_BITOR(lhs, rhs, pres) ((*(pres) = (lhs | rhs)), false) | 710 #define SMI_BITOR(lhs, rhs, pres) ((*(pres) = (lhs | rhs)), false) |
735 #define SMI_BITAND(lhs, rhs, pres) ((*(pres) = ((lhs) & (rhs))), false) | 711 #define SMI_BITAND(lhs, rhs, pres) ((*(pres) = ((lhs) & (rhs))), false) |
736 #define SMI_BITXOR(lhs, rhs, pres) ((*(pres) = ((lhs) ^ (rhs))), false) | 712 #define SMI_BITXOR(lhs, rhs, pres) ((*(pres) = ((lhs) ^ (rhs))), false) |
737 | 713 |
738 | 714 |
739 void Simulator::CallRuntime(Thread* thread, | 715 void Simulator::CallRuntime(Thread* thread, |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 handler = DRT_InlineCacheMissHandlerThreeArgs; | 794 handler = DRT_InlineCacheMissHandlerThreeArgs; |
819 break; | 795 break; |
820 default: | 796 default: |
821 UNREACHABLE(); | 797 UNREACHABLE(); |
822 break; | 798 break; |
823 } | 799 } |
824 | 800 |
825 // Handler arguments: arguments to check and an ICData object. | 801 // Handler arguments: arguments to check and an ICData object. |
826 const intptr_t miss_handler_argc = checked_args + 1; | 802 const intptr_t miss_handler_argc = checked_args + 1; |
827 RawObject** exit_frame = miss_handler_args + miss_handler_argc; | 803 RawObject** exit_frame = miss_handler_args + miss_handler_argc; |
828 CallRuntime(thread, | 804 CallRuntime(thread, FP, exit_frame, pc, miss_handler_argc, miss_handler_args, |
829 FP, | 805 result, reinterpret_cast<uword>(handler)); |
830 exit_frame, | |
831 pc, | |
832 miss_handler_argc, | |
833 miss_handler_args, | |
834 result, | |
835 reinterpret_cast<uword>(handler)); | |
836 } | 806 } |
837 | 807 |
838 | 808 |
839 DART_FORCE_INLINE void Simulator::InstanceCall1(Thread* thread, | 809 DART_FORCE_INLINE void Simulator::InstanceCall1(Thread* thread, |
840 RawICData* icdata, | 810 RawICData* icdata, |
841 RawObject** call_base, | 811 RawObject** call_base, |
842 RawObject** top, | 812 RawObject** top, |
843 RawArray** argdesc, | 813 RawArray** argdesc, |
844 RawObjectPool** pp, | 814 RawObjectPool** pp, |
845 uint32_t** pc, | 815 uint32_t** pc, |
846 RawObject*** FP, | 816 RawObject*** FP, |
847 RawObject*** SP, | 817 RawObject*** SP, |
848 bool optimized) { | 818 bool optimized) { |
849 ASSERT(icdata->GetClassId() == kICDataCid); | 819 ASSERT(icdata->GetClassId() == kICDataCid); |
850 | 820 |
851 const intptr_t kCheckedArgs = 1; | 821 const intptr_t kCheckedArgs = 1; |
852 RawObject** args = call_base; | 822 RawObject** args = call_base; |
853 RawArray* cache = icdata->ptr()->ic_data_->ptr(); | 823 RawArray* cache = icdata->ptr()->ic_data_->ptr(); |
854 | 824 |
855 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); | 825 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); |
856 | 826 |
857 bool found = false; | 827 bool found = false; |
858 const intptr_t length = Smi::Value(cache->length_); | 828 const intptr_t length = Smi::Value(cache->length_); |
859 intptr_t i; | 829 intptr_t i; |
860 for (i = 0; | 830 for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { |
861 i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { | |
862 if (cache->data()[i + 0] == receiver_cid) { | 831 if (cache->data()[i + 0] == receiver_cid) { |
863 top[0] = cache->data()[i + kCheckedArgs]; | 832 top[0] = cache->data()[i + kCheckedArgs]; |
864 found = true; | 833 found = true; |
865 break; | 834 break; |
866 } | 835 } |
867 } | 836 } |
868 | 837 |
869 if (found) { | 838 if (found) { |
870 if (!optimized) { | 839 if (!optimized) { |
871 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); | 840 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); |
872 } | 841 } |
873 } else { | 842 } else { |
874 InlineCacheMiss( | 843 InlineCacheMiss(kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, |
875 kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP); | 844 *SP); |
876 } | 845 } |
877 | 846 |
878 *argdesc = icdata->ptr()->args_descriptor_; | 847 *argdesc = icdata->ptr()->args_descriptor_; |
879 Invoke(thread, call_base, top, pp, pc, FP, SP); | 848 Invoke(thread, call_base, top, pp, pc, FP, SP); |
880 } | 849 } |
881 | 850 |
882 | 851 |
883 DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread, | 852 DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread, |
884 RawICData* icdata, | 853 RawICData* icdata, |
885 RawObject** call_base, | 854 RawObject** call_base, |
886 RawObject** top, | 855 RawObject** top, |
887 RawArray** argdesc, | 856 RawArray** argdesc, |
888 RawObjectPool** pp, | 857 RawObjectPool** pp, |
889 uint32_t** pc, | 858 uint32_t** pc, |
890 RawObject*** FP, | 859 RawObject*** FP, |
891 RawObject*** SP, | 860 RawObject*** SP, |
892 bool optimized) { | 861 bool optimized) { |
893 ASSERT(icdata->GetClassId() == kICDataCid); | 862 ASSERT(icdata->GetClassId() == kICDataCid); |
894 | 863 |
895 const intptr_t kCheckedArgs = 2; | 864 const intptr_t kCheckedArgs = 2; |
896 RawObject** args = call_base; | 865 RawObject** args = call_base; |
897 RawArray* cache = icdata->ptr()->ic_data_->ptr(); | 866 RawArray* cache = icdata->ptr()->ic_data_->ptr(); |
898 | 867 |
899 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); | 868 RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]); |
900 RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[1]); | 869 RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[1]); |
901 | 870 |
902 bool found = false; | 871 bool found = false; |
903 const intptr_t length = Smi::Value(cache->length_); | 872 const intptr_t length = Smi::Value(cache->length_); |
904 intptr_t i; | 873 intptr_t i; |
905 for (i = 0; | 874 for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { |
906 i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) { | |
907 if ((cache->data()[i + 0] == receiver_cid) && | 875 if ((cache->data()[i + 0] == receiver_cid) && |
908 (cache->data()[i + 1] == arg0_cid)) { | 876 (cache->data()[i + 1] == arg0_cid)) { |
909 top[0] = cache->data()[i + kCheckedArgs]; | 877 top[0] = cache->data()[i + kCheckedArgs]; |
910 found = true; | 878 found = true; |
911 break; | 879 break; |
912 } | 880 } |
913 } | 881 } |
914 | 882 |
915 if (found) { | 883 if (found) { |
916 if (!optimized) { | 884 if (!optimized) { |
917 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); | 885 SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs); |
918 } | 886 } |
919 } else { | 887 } else { |
920 InlineCacheMiss( | 888 InlineCacheMiss(kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, |
921 kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP); | 889 *SP); |
922 } | 890 } |
923 | 891 |
924 *argdesc = icdata->ptr()->args_descriptor_; | 892 *argdesc = icdata->ptr()->args_descriptor_; |
925 Invoke(thread, call_base, top, pp, pc, FP, SP); | 893 Invoke(thread, call_base, top, pp, pc, FP, SP); |
926 } | 894 } |
927 | 895 |
928 | 896 |
929 // Note: functions below are marked DART_NOINLINE to recover performance on | 897 // Note: functions below are marked DART_NOINLINE to recover performance on |
930 // ARM where inlining these functions into the interpreter loop seemed to cause | 898 // ARM where inlining these functions into the interpreter loop seemed to cause |
931 // some code quality issues. | 899 // some code quality issues. |
932 static DART_NOINLINE bool InvokeRuntime( | 900 static DART_NOINLINE bool InvokeRuntime(Thread* thread, |
933 Thread* thread, | 901 Simulator* sim, |
934 Simulator* sim, | 902 RuntimeFunction drt, |
935 RuntimeFunction drt, | 903 const NativeArguments& args) { |
936 const NativeArguments& args) { | |
937 SimulatorSetjmpBuffer buffer(sim); | 904 SimulatorSetjmpBuffer buffer(sim); |
938 if (!setjmp(buffer.buffer_)) { | 905 if (!setjmp(buffer.buffer_)) { |
939 thread->set_vm_tag(reinterpret_cast<uword>(drt)); | 906 thread->set_vm_tag(reinterpret_cast<uword>(drt)); |
940 drt(args); | 907 drt(args); |
941 thread->set_vm_tag(VMTag::kDartTagId); | 908 thread->set_vm_tag(VMTag::kDartTagId); |
942 thread->set_top_exit_frame_info(0); | 909 thread->set_top_exit_frame_info(0); |
943 return true; | 910 return true; |
944 } else { | 911 } else { |
945 return false; | 912 return false; |
946 } | 913 } |
947 } | 914 } |
948 | 915 |
949 | 916 |
950 static DART_NOINLINE bool InvokeNative( | 917 static DART_NOINLINE bool InvokeNative(Thread* thread, |
951 Thread* thread, | 918 Simulator* sim, |
952 Simulator* sim, | 919 SimulatorBootstrapNativeCall f, |
953 SimulatorBootstrapNativeCall f, | 920 NativeArguments* args) { |
954 NativeArguments* args) { | |
955 SimulatorSetjmpBuffer buffer(sim); | 921 SimulatorSetjmpBuffer buffer(sim); |
956 if (!setjmp(buffer.buffer_)) { | 922 if (!setjmp(buffer.buffer_)) { |
957 thread->set_vm_tag(reinterpret_cast<uword>(f)); | 923 thread->set_vm_tag(reinterpret_cast<uword>(f)); |
958 f(args); | 924 f(args); |
959 thread->set_vm_tag(VMTag::kDartTagId); | 925 thread->set_vm_tag(VMTag::kDartTagId); |
960 thread->set_top_exit_frame_info(0); | 926 thread->set_top_exit_frame_info(0); |
961 return true; | 927 return true; |
962 } else { | 928 } else { |
963 return false; | 929 return false; |
964 } | 930 } |
965 } | 931 } |
966 | 932 |
967 | 933 |
968 static DART_NOINLINE bool InvokeNativeWrapper( | 934 static DART_NOINLINE bool InvokeNativeWrapper(Thread* thread, |
969 Thread* thread, | 935 Simulator* sim, |
970 Simulator* sim, | 936 Dart_NativeFunction f, |
971 Dart_NativeFunction f, | 937 NativeArguments* args) { |
972 NativeArguments* args) { | |
973 SimulatorSetjmpBuffer buffer(sim); | 938 SimulatorSetjmpBuffer buffer(sim); |
974 if (!setjmp(buffer.buffer_)) { | 939 if (!setjmp(buffer.buffer_)) { |
975 thread->set_vm_tag(reinterpret_cast<uword>(f)); | 940 thread->set_vm_tag(reinterpret_cast<uword>(f)); |
976 NativeEntry::NativeCallWrapper(reinterpret_cast<Dart_NativeArguments>(args), | 941 NativeEntry::NativeCallWrapper(reinterpret_cast<Dart_NativeArguments>(args), |
977 f); | 942 f); |
978 thread->set_vm_tag(VMTag::kDartTagId); | 943 thread->set_vm_tag(VMTag::kDartTagId); |
979 thread->set_top_exit_frame_info(0); | 944 thread->set_top_exit_frame_info(0); |
980 return true; | 945 return true; |
981 } else { | 946 } else { |
982 return false; | 947 return false; |
983 } | 948 } |
984 } | 949 } |
985 | 950 |
986 // Note: all macro helpers are intended to be used only inside Simulator::Call. | 951 // Note: all macro helpers are intended to be used only inside Simulator::Call. |
987 | 952 |
988 // Decode opcode and A part of the given value and dispatch to the | 953 // Decode opcode and A part of the given value and dispatch to the |
989 // corresponding bytecode handler. | 954 // corresponding bytecode handler. |
990 #define DISPATCH_OP(val) \ | 955 #define DISPATCH_OP(val) \ |
991 do { \ | 956 do { \ |
992 op = (val); \ | 957 op = (val); \ |
993 rA = ((op >> 8) & 0xFF); \ | 958 rA = ((op >> 8) & 0xFF); \ |
994 goto* dispatch[op & 0xFF]; \ | 959 goto* dispatch[op & 0xFF]; \ |
995 } while (0) | 960 } while (0) |
996 | 961 |
997 // Fetch next operation from PC, increment program counter and dispatch. | 962 // Fetch next operation from PC, increment program counter and dispatch. |
998 #define DISPATCH() DISPATCH_OP(*pc++) | 963 #define DISPATCH() DISPATCH_OP(*pc++) |
999 | 964 |
1000 // Define entry point that handles bytecode Name with the given operand format. | 965 // Define entry point that handles bytecode Name with the given operand format. |
1001 #define BYTECODE(Name, Operands) \ | 966 #define BYTECODE(Name, Operands) \ |
1002 BYTECODE_HEADER(Name, DECLARE_##Operands, DECODE_##Operands) | 967 BYTECODE_HEADER(Name, DECLARE_##Operands, DECODE_##Operands) |
1003 | 968 |
1004 #define BYTECODE_HEADER(Name, Declare, Decode) \ | 969 #define BYTECODE_HEADER(Name, Declare, Decode) \ |
1005 Declare; \ | 970 Declare; \ |
1006 bc##Name : Decode \ | 971 bc##Name : Decode |
1007 | 972 |
1008 // Helpers to decode common instruction formats. Used in conjunction with | 973 // Helpers to decode common instruction formats. Used in conjunction with |
1009 // BYTECODE() macro. | 974 // BYTECODE() macro. |
1010 #define DECLARE_A_B_C uint16_t rB, rC; USE(rB); USE(rC) | 975 #define DECLARE_A_B_C \ |
1011 #define DECODE_A_B_C \ | 976 uint16_t rB, rC; \ |
1012 rB = ((op >> Bytecode::kBShift) & Bytecode::kBMask); \ | 977 USE(rB); \ |
| 978 USE(rC) |
| 979 #define DECODE_A_B_C \ |
| 980 rB = ((op >> Bytecode::kBShift) & Bytecode::kBMask); \ |
1013 rC = ((op >> Bytecode::kCShift) & Bytecode::kCMask); | 981 rC = ((op >> Bytecode::kCShift) & Bytecode::kCMask); |
1014 | 982 |
1015 #define DECLARE_0 | 983 #define DECLARE_0 |
1016 #define DECODE_0 | 984 #define DECODE_0 |
1017 | 985 |
1018 #define DECLARE_A | 986 #define DECLARE_A |
1019 #define DECODE_A | 987 #define DECODE_A |
1020 | 988 |
1021 #define DECLARE___D uint32_t rD; USE(rD) | 989 #define DECLARE___D \ |
| 990 uint32_t rD; \ |
| 991 USE(rD) |
1022 #define DECODE___D rD = (op >> Bytecode::kDShift); | 992 #define DECODE___D rD = (op >> Bytecode::kDShift); |
1023 | 993 |
1024 #define DECLARE_A_D DECLARE___D | 994 #define DECLARE_A_D DECLARE___D |
1025 #define DECODE_A_D DECODE___D | 995 #define DECODE_A_D DECODE___D |
1026 | 996 |
1027 #define DECLARE_A_X int32_t rD; USE(rD) | 997 #define DECLARE_A_X \ |
| 998 int32_t rD; \ |
| 999 USE(rD) |
1028 #define DECODE_A_X rD = (static_cast<int32_t>(op) >> Bytecode::kDShift); | 1000 #define DECODE_A_X rD = (static_cast<int32_t>(op) >> Bytecode::kDShift); |
1029 | 1001 |
1030 | 1002 |
1031 #define SMI_FASTPATH_ICDATA_INC \ | 1003 #define SMI_FASTPATH_ICDATA_INC \ |
1032 do { \ | 1004 do { \ |
1033 ASSERT(Bytecode::IsCallOpcode(*pc)); \ | 1005 ASSERT(Bytecode::IsCallOpcode(*pc)); \ |
1034 const uint16_t kidx = Bytecode::DecodeD(*pc); \ | 1006 const uint16_t kidx = Bytecode::DecodeD(*pc); \ |
1035 const RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); \ | 1007 const RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); \ |
1036 RawObject** entries = icdata->ptr()->ic_data_->ptr()->data(); \ | 1008 RawObject** entries = icdata->ptr()->ic_data_->ptr()->data(); \ |
1037 SimulatorHelpers::IncrementICUsageCount(entries, 0, 2); \ | 1009 SimulatorHelpers::IncrementICUsageCount(entries, 0, 2); \ |
1038 } while (0); \ | 1010 } while (0); |
1039 | 1011 |
1040 // Declare bytecode handler for a smi operation (e.g. AddTOS) with the | 1012 // Declare bytecode handler for a smi operation (e.g. AddTOS) with the |
1041 // given result type and the given behavior specified as a function | 1013 // given result type and the given behavior specified as a function |
1042 // that takes left and right operands and result slot and returns | 1014 // that takes left and right operands and result slot and returns |
1043 // true if fast-path succeeds. | 1015 // true if fast-path succeeds. |
1044 #define SMI_FASTPATH_TOS(ResultT, Func) \ | 1016 #define SMI_FASTPATH_TOS(ResultT, Func) \ |
1045 { \ | 1017 { \ |
1046 const intptr_t lhs = reinterpret_cast<intptr_t>(SP[-1]); \ | 1018 const intptr_t lhs = reinterpret_cast<intptr_t>(SP[-1]); \ |
1047 const intptr_t rhs = reinterpret_cast<intptr_t>(SP[-0]); \ | 1019 const intptr_t rhs = reinterpret_cast<intptr_t>(SP[-0]); \ |
1048 ResultT* slot = reinterpret_cast<ResultT*>(SP - 1); \ | 1020 ResultT* slot = reinterpret_cast<ResultT*>(SP - 1); \ |
1049 if (LIKELY(!thread->isolate()->single_step()) && \ | 1021 if (LIKELY(!thread->isolate()->single_step()) && \ |
1050 LIKELY(AreBothSmis(lhs, rhs) && \ | 1022 LIKELY(AreBothSmis(lhs, rhs) && !Func(lhs, rhs, slot))) { \ |
1051 !Func(lhs, rhs, slot))) { \ | |
1052 SMI_FASTPATH_ICDATA_INC; \ | 1023 SMI_FASTPATH_ICDATA_INC; \ |
1053 /* Fast path succeeded. Skip the generic call that follows. */ \ | 1024 /* Fast path succeeded. Skip the generic call that follows. */ \ |
1054 pc++; \ | 1025 pc++; \ |
1055 /* We dropped 2 arguments and push result */ \ | 1026 /* We dropped 2 arguments and push result */ \ |
1056 SP--; \ | 1027 SP--; \ |
1057 } \ | 1028 } \ |
1058 } | 1029 } |
1059 | 1030 |
1060 // Skip the next instruction if there is no overflow. | 1031 // Skip the next instruction if there is no overflow. |
1061 #define SMI_OP_CHECK(ResultT, Func) \ | 1032 #define SMI_OP_CHECK(ResultT, Func) \ |
1062 { \ | 1033 { \ |
1063 const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]); \ | 1034 const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]); \ |
1064 const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]); \ | 1035 const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]); \ |
1065 ResultT* slot = reinterpret_cast<ResultT*>(&FP[rA]); \ | 1036 ResultT* slot = reinterpret_cast<ResultT*>(&FP[rA]); \ |
1066 if (LIKELY(!Func(lhs, rhs, slot))) { \ | 1037 if (LIKELY(!Func(lhs, rhs, slot))) { \ |
1067 /* Success. Skip the instruction that follows. */ \ | 1038 /* Success. Skip the instruction that follows. */ \ |
1068 pc++; \ | 1039 pc++; \ |
1069 } \ | 1040 } \ |
1070 } | 1041 } |
1071 | 1042 |
1072 // Do not check for overflow. | 1043 // Do not check for overflow. |
1073 #define SMI_OP_NOCHECK(ResultT, Func) \ | 1044 #define SMI_OP_NOCHECK(ResultT, Func) \ |
1074 { \ | 1045 { \ |
1075 const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]); \ | 1046 const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]); \ |
1076 const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]); \ | 1047 const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]); \ |
1077 ResultT* slot = reinterpret_cast<ResultT*>(&FP[rA]); \ | 1048 ResultT* slot = reinterpret_cast<ResultT*>(&FP[rA]); \ |
1078 Func(lhs, rhs, slot); \ | 1049 Func(lhs, rhs, slot); \ |
1079 } \ | 1050 } |
1080 | 1051 |
1081 | 1052 |
1082 // Exception handling helper. Gets handler FP and PC from the Simulator where | 1053 // Exception handling helper. Gets handler FP and PC from the Simulator where |
1083 // they were stored by Simulator::Longjmp and proceeds to execute the handler. | 1054 // they were stored by Simulator::Longjmp and proceeds to execute the handler. |
1084 // Corner case: handler PC can be a fake marker that marks entry frame, which | 1055 // Corner case: handler PC can be a fake marker that marks entry frame, which |
1085 // means exception was not handled in the Dart code. In this case we return | 1056 // means exception was not handled in the Dart code. In this case we return |
1086 // caught exception from Simulator::Call. | 1057 // caught exception from Simulator::Call. |
1087 #define HANDLE_EXCEPTION \ | 1058 #define HANDLE_EXCEPTION \ |
1088 do { \ | 1059 do { \ |
1089 FP = reinterpret_cast<RawObject**>(fp_); \ | 1060 FP = reinterpret_cast<RawObject**>(fp_); \ |
1090 pc = reinterpret_cast<uint32_t*>(pc_); \ | 1061 pc = reinterpret_cast<uint32_t*>(pc_); \ |
1091 if ((reinterpret_cast<uword>(pc) & 2) != 0) { /* Entry frame? */ \ | 1062 if ((reinterpret_cast<uword>(pc) & 2) != 0) { /* Entry frame? */ \ |
1092 fp_ = sp_ = reinterpret_cast<RawObject**>(fp_[0]); \ | 1063 fp_ = sp_ = reinterpret_cast<RawObject**>(fp_[0]); \ |
1093 thread->set_top_exit_frame_info(reinterpret_cast<uword>(sp_)); \ | 1064 thread->set_top_exit_frame_info(reinterpret_cast<uword>(sp_)); \ |
1094 thread->set_top_resource(top_resource); \ | 1065 thread->set_top_resource(top_resource); \ |
1095 thread->set_vm_tag(vm_tag); \ | 1066 thread->set_vm_tag(vm_tag); \ |
1096 return special_[kExceptionSpecialIndex]; \ | 1067 return special_[kExceptionSpecialIndex]; \ |
1097 } \ | 1068 } \ |
1098 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); \ | 1069 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); \ |
1099 goto DispatchAfterException; \ | 1070 goto DispatchAfterException; \ |
1100 } while (0) \ | 1071 } while (0) |
1101 | 1072 |
1102 // Runtime call helpers: handle invocation and potential exception after return. | 1073 // Runtime call helpers: handle invocation and potential exception after return. |
1103 #define INVOKE_RUNTIME(Func, Args) \ | 1074 #define INVOKE_RUNTIME(Func, Args) \ |
1104 if (!InvokeRuntime(thread, this, Func, Args)) { \ | 1075 if (!InvokeRuntime(thread, this, Func, Args)) { \ |
1105 HANDLE_EXCEPTION; \ | 1076 HANDLE_EXCEPTION; \ |
1106 } \ | 1077 } |
1107 | 1078 |
1108 #define INVOKE_NATIVE(Func, Args) \ | 1079 #define INVOKE_NATIVE(Func, Args) \ |
1109 if (!InvokeNative(thread, this, Func, &Args)) { \ | 1080 if (!InvokeNative(thread, this, Func, &Args)) { \ |
1110 HANDLE_EXCEPTION; \ | 1081 HANDLE_EXCEPTION; \ |
1111 } \ | 1082 } |
1112 | 1083 |
1113 #define INVOKE_NATIVE_WRAPPER(Func, Args) \ | 1084 #define INVOKE_NATIVE_WRAPPER(Func, Args) \ |
1114 if (!InvokeNativeWrapper(thread, this, Func, &Args)) { \ | 1085 if (!InvokeNativeWrapper(thread, this, Func, &Args)) { \ |
1115 HANDLE_EXCEPTION; \ | 1086 HANDLE_EXCEPTION; \ |
1116 } \ | 1087 } |
1117 | 1088 |
1118 #define LOAD_CONSTANT(index) (pp->data()[(index)].raw_obj_) | 1089 #define LOAD_CONSTANT(index) (pp->data()[(index)].raw_obj_) |
1119 | 1090 |
1120 RawObject* Simulator::Call(const Code& code, | 1091 RawObject* Simulator::Call(const Code& code, |
1121 const Array& arguments_descriptor, | 1092 const Array& arguments_descriptor, |
1122 const Array& arguments, | 1093 const Array& arguments, |
1123 Thread* thread) { | 1094 Thread* thread) { |
1124 // Dispatch used to interpret bytecode. Contains addresses of | 1095 // Dispatch used to interpret bytecode. Contains addresses of |
1125 // labels of bytecode handlers. Handlers themselves are defined below. | 1096 // labels of bytecode handlers. Handlers themselves are defined below. |
1126 static const void* dispatch[] = { | 1097 static const void* dispatch[] = { |
1127 #define TARGET(name, fmt, fmta, fmtb, fmtc) &&bc##name, | 1098 #define TARGET(name, fmt, fmta, fmtb, fmtc) &&bc##name, |
1128 BYTECODES_LIST(TARGET) | 1099 BYTECODES_LIST(TARGET) |
1129 #undef TARGET | 1100 #undef TARGET |
1130 }; | 1101 }; |
1131 | 1102 |
1132 // Interpreter state (see constants_dbc.h for high-level overview). | 1103 // Interpreter state (see constants_dbc.h for high-level overview). |
1133 uint32_t* pc; // Program Counter: points to the next op to execute. | 1104 uint32_t* pc; // Program Counter: points to the next op to execute. |
1134 RawObjectPool* pp; // Pool Pointer. | 1105 RawObjectPool* pp; // Pool Pointer. |
1135 RawObject** FP; // Frame Pointer. | 1106 RawObject** FP; // Frame Pointer. |
1136 RawObject** SP; // Stack Pointer. | 1107 RawObject** SP; // Stack Pointer. |
1137 | 1108 |
1138 RawArray* argdesc; // Arguments Descriptor: used to pass information between | 1109 RawArray* argdesc; // Arguments Descriptor: used to pass information between |
1139 // call instruction and the function entry. | 1110 // call instruction and the function entry. |
1140 | 1111 |
1141 uint32_t op; // Currently executing op. | 1112 uint32_t op; // Currently executing op. |
1142 uint16_t rA; // A component of the currently executing op. | 1113 uint16_t rA; // A component of the currently executing op. |
1143 | 1114 |
1144 if (sp_ == NULL) { | 1115 if (sp_ == NULL) { |
1145 fp_ = sp_ = reinterpret_cast<RawObject**>(stack_); | 1116 fp_ = sp_ = reinterpret_cast<RawObject**>(stack_); |
1146 } | 1117 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1294 memmove(FP, first_arg, pos_count * kWordSize); | 1265 memmove(FP, first_arg, pos_count * kWordSize); |
1295 | 1266 |
1296 if (num_opt_named_params != 0) { | 1267 if (num_opt_named_params != 0) { |
1297 // This is a function with named parameters. | 1268 // This is a function with named parameters. |
1298 // Walk the list of named parameters and their | 1269 // Walk the list of named parameters and their |
1299 // default values encoded as pairs of LoadConstant instructions that | 1270 // default values encoded as pairs of LoadConstant instructions that |
1300 // follows the entry point and find matching values via arguments | 1271 // follows the entry point and find matching values via arguments |
1301 // descriptor. | 1272 // descriptor. |
1302 RawObject** argdesc_data = argdesc->ptr()->data(); | 1273 RawObject** argdesc_data = argdesc->ptr()->data(); |
1303 | 1274 |
1304 intptr_t i = named_count - 1; // argument position | 1275 intptr_t i = named_count - 1; // argument position |
1305 intptr_t j = num_opt_named_params - 1; // parameter position | 1276 intptr_t j = num_opt_named_params - 1; // parameter position |
1306 while ((j >= 0) && (i >= 0)) { | 1277 while ((j >= 0) && (i >= 0)) { |
1307 // Fetch formal parameter information: name, default value, target slot. | 1278 // Fetch formal parameter information: name, default value, target slot. |
1308 const uint32_t load_name = pc[2 * j]; | 1279 const uint32_t load_name = pc[2 * j]; |
1309 const uint32_t load_value = pc[2 * j + 1]; | 1280 const uint32_t load_value = pc[2 * j + 1]; |
1310 ASSERT(Bytecode::DecodeOpcode(load_name) == Bytecode::kLoadConstant); | 1281 ASSERT(Bytecode::DecodeOpcode(load_name) == Bytecode::kLoadConstant); |
1311 ASSERT(Bytecode::DecodeOpcode(load_value) == Bytecode::kLoadConstant); | 1282 ASSERT(Bytecode::DecodeOpcode(load_value) == Bytecode::kLoadConstant); |
1312 const uint8_t reg = Bytecode::DecodeA(load_name); | 1283 const uint8_t reg = Bytecode::DecodeA(load_name); |
1313 ASSERT(reg == Bytecode::DecodeA(load_value)); | 1284 ASSERT(reg == Bytecode::DecodeA(load_value)); |
1314 | 1285 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1358 if (named_count != 0) { | 1329 if (named_count != 0) { |
1359 // Function can't have both named and optional positional parameters. | 1330 // Function can't have both named and optional positional parameters. |
1360 // This kind of mismatch can only occur if the current function | 1331 // This kind of mismatch can only occur if the current function |
1361 // is a closure. | 1332 // is a closure. |
1362 goto ClosureNoSuchMethod; | 1333 goto ClosureNoSuchMethod; |
1363 } | 1334 } |
1364 | 1335 |
1365 // Process the list of default values encoded as a sequence of | 1336 // Process the list of default values encoded as a sequence of |
1366 // LoadConstant instructions after EntryOpt bytecode. | 1337 // LoadConstant instructions after EntryOpt bytecode. |
1367 // Execute only those that correspond to parameters the were not passed. | 1338 // Execute only those that correspond to parameters the were not passed. |
1368 for (intptr_t i = pos_count - num_fixed_params; | 1339 for (intptr_t i = pos_count - num_fixed_params; i < num_opt_pos_params; |
1369 i < num_opt_pos_params; | |
1370 i++) { | 1340 i++) { |
1371 const uint32_t load_value = pc[i]; | 1341 const uint32_t load_value = pc[i]; |
1372 ASSERT(Bytecode::DecodeOpcode(load_value) == Bytecode::kLoadConstant); | 1342 ASSERT(Bytecode::DecodeOpcode(load_value) == Bytecode::kLoadConstant); |
1373 #if defined(DEBUG) | 1343 #if defined(DEBUG) |
1374 const uint8_t reg = Bytecode::DecodeA(load_value); | 1344 const uint8_t reg = Bytecode::DecodeA(load_value); |
1375 ASSERT((num_fixed_params + i) == reg); | 1345 ASSERT((num_fixed_params + i) == reg); |
1376 #endif | 1346 #endif |
1377 FP[num_fixed_params + i] = LOAD_CONSTANT(Bytecode::DecodeD(load_value)); | 1347 FP[num_fixed_params + i] = LOAD_CONSTANT(Bytecode::DecodeD(load_value)); |
1378 } | 1348 } |
1379 | 1349 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1421 pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_); | 1391 pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_); |
1422 pc_ = reinterpret_cast<uword>(pc); // For the profiler. | 1392 pc_ = reinterpret_cast<uword>(pc); // For the profiler. |
1423 } | 1393 } |
1424 DISPATCH(); | 1394 DISPATCH(); |
1425 } | 1395 } |
1426 | 1396 |
1427 { | 1397 { |
1428 BYTECODE(HotCheck, A_D); | 1398 BYTECODE(HotCheck, A_D); |
1429 const uint8_t increment = rA; | 1399 const uint8_t increment = rA; |
1430 const uint16_t threshold = rD; | 1400 const uint16_t threshold = rD; |
1431 RawFunction* f = FrameFunction(FP); | 1401 RawFunction* f = FrameFunction(FP); |
1432 int32_t counter = f->ptr()->usage_counter_; | 1402 int32_t counter = f->ptr()->usage_counter_; |
1433 // Note: we don't increment usage counter in the prologue of optimized | 1403 // Note: we don't increment usage counter in the prologue of optimized |
1434 // functions. | 1404 // functions. |
1435 if (increment) { | 1405 if (increment) { |
1436 counter += increment; | 1406 counter += increment; |
1437 f->ptr()->usage_counter_ = counter; | 1407 f->ptr()->usage_counter_ = counter; |
1438 } | 1408 } |
1439 if (UNLIKELY(counter >= threshold)) { | 1409 if (UNLIKELY(counter >= threshold)) { |
1440 FP[0] = f; | 1410 FP[0] = f; |
1441 FP[1] = 0; | 1411 FP[1] = 0; |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1666 } | 1636 } |
1667 | 1637 |
1668 // Invoke target function. | 1638 // Invoke target function. |
1669 { | 1639 { |
1670 const uint16_t argc = rA; | 1640 const uint16_t argc = rA; |
1671 // Lookup the funciton in the ICData. | 1641 // Lookup the funciton in the ICData. |
1672 RawObject* ic_data_obj = SP[0]; | 1642 RawObject* ic_data_obj = SP[0]; |
1673 RawICData* ic_data = RAW_CAST(ICData, ic_data_obj); | 1643 RawICData* ic_data = RAW_CAST(ICData, ic_data_obj); |
1674 RawObject** data = ic_data->ptr()->ic_data_->ptr()->data(); | 1644 RawObject** data = ic_data->ptr()->ic_data_->ptr()->data(); |
1675 SimulatorHelpers::IncrementICUsageCount(data, 0, 0); | 1645 SimulatorHelpers::IncrementICUsageCount(data, 0, 0); |
1676 SP[0] = data[ICData::TargetIndexFor( | 1646 SP[0] = data[ICData::TargetIndexFor(ic_data->ptr()->state_bits_ & 0x3)]; |
1677 ic_data->ptr()->state_bits_ & 0x3)]; | |
1678 RawObject** call_base = SP - argc; | 1647 RawObject** call_base = SP - argc; |
1679 RawObject** call_top = SP; // *SP contains function | 1648 RawObject** call_top = SP; // *SP contains function |
1680 argdesc = static_cast<RawArray*>(LOAD_CONSTANT(rD)); | 1649 argdesc = static_cast<RawArray*>(LOAD_CONSTANT(rD)); |
1681 Invoke(thread, call_base, call_top, &pp, &pc, &FP, &SP); | 1650 Invoke(thread, call_base, call_top, &pp, &pc, &FP, &SP); |
1682 } | 1651 } |
1683 | 1652 |
1684 DISPATCH(); | 1653 DISPATCH(); |
1685 } | 1654 } |
1686 | 1655 |
1687 { | 1656 { |
(...skipping 19 matching lines...) Expand all Loading... |
1707 { | 1676 { |
1708 const uint16_t argc = rA; | 1677 const uint16_t argc = rA; |
1709 const uint16_t kidx = rD; | 1678 const uint16_t kidx = rD; |
1710 | 1679 |
1711 RawObject** call_base = SP - argc + 1; | 1680 RawObject** call_base = SP - argc + 1; |
1712 RawObject** call_top = SP + 1; | 1681 RawObject** call_top = SP + 1; |
1713 | 1682 |
1714 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); | 1683 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1715 SimulatorHelpers::IncrementUsageCounter( | 1684 SimulatorHelpers::IncrementUsageCounter( |
1716 RAW_CAST(Function, icdata->ptr()->owner_)); | 1685 RAW_CAST(Function, icdata->ptr()->owner_)); |
1717 InstanceCall1(thread, icdata, call_base, call_top, | 1686 InstanceCall1(thread, icdata, call_base, call_top, &argdesc, &pp, &pc, |
1718 &argdesc, &pp, &pc, &FP, &SP, | 1687 &FP, &SP, false /* optimized */); |
1719 false /* optimized */); | |
1720 } | 1688 } |
1721 | 1689 |
1722 DISPATCH(); | 1690 DISPATCH(); |
1723 } | 1691 } |
1724 | 1692 |
1725 { | 1693 { |
1726 BYTECODE(InstanceCall2, A_D); | 1694 BYTECODE(InstanceCall2, A_D); |
1727 if (thread->isolate()->single_step()) { | 1695 if (thread->isolate()->single_step()) { |
1728 Exit(thread, FP, SP + 1, pc); | 1696 Exit(thread, FP, SP + 1, pc); |
1729 NativeArguments args(thread, 0, NULL, NULL); | 1697 NativeArguments args(thread, 0, NULL, NULL); |
1730 INVOKE_RUNTIME(DRT_SingleStepHandler, args); | 1698 INVOKE_RUNTIME(DRT_SingleStepHandler, args); |
1731 } | 1699 } |
1732 | 1700 |
1733 { | 1701 { |
1734 const uint16_t argc = rA; | 1702 const uint16_t argc = rA; |
1735 const uint16_t kidx = rD; | 1703 const uint16_t kidx = rD; |
1736 | 1704 |
1737 RawObject** call_base = SP - argc + 1; | 1705 RawObject** call_base = SP - argc + 1; |
1738 RawObject** call_top = SP + 1; | 1706 RawObject** call_top = SP + 1; |
1739 | 1707 |
1740 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); | 1708 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1741 SimulatorHelpers::IncrementUsageCounter( | 1709 SimulatorHelpers::IncrementUsageCounter( |
1742 RAW_CAST(Function, icdata->ptr()->owner_)); | 1710 RAW_CAST(Function, icdata->ptr()->owner_)); |
1743 InstanceCall2(thread, icdata, call_base, call_top, | 1711 InstanceCall2(thread, icdata, call_base, call_top, &argdesc, &pp, &pc, |
1744 &argdesc, &pp, &pc, &FP, &SP, | 1712 &FP, &SP, false /* optimized */); |
1745 false /* optimized */); | |
1746 } | 1713 } |
1747 | 1714 |
1748 DISPATCH(); | 1715 DISPATCH(); |
1749 } | 1716 } |
1750 | 1717 |
1751 { | 1718 { |
1752 BYTECODE(InstanceCall1Opt, A_D); | 1719 BYTECODE(InstanceCall1Opt, A_D); |
1753 | 1720 |
1754 { | 1721 { |
1755 const uint16_t argc = rA; | 1722 const uint16_t argc = rA; |
1756 const uint16_t kidx = rD; | 1723 const uint16_t kidx = rD; |
1757 | 1724 |
1758 RawObject** call_base = SP - argc + 1; | 1725 RawObject** call_base = SP - argc + 1; |
1759 RawObject** call_top = SP + 1; | 1726 RawObject** call_top = SP + 1; |
1760 | 1727 |
1761 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); | 1728 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1762 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); | 1729 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); |
1763 InstanceCall1(thread, icdata, call_base, call_top, | 1730 InstanceCall1(thread, icdata, call_base, call_top, &argdesc, &pp, &pc, |
1764 &argdesc, &pp, &pc, &FP, &SP, | 1731 &FP, &SP, true /* optimized */); |
1765 true /* optimized */); | |
1766 } | 1732 } |
1767 | 1733 |
1768 DISPATCH(); | 1734 DISPATCH(); |
1769 } | 1735 } |
1770 | 1736 |
1771 { | 1737 { |
1772 BYTECODE(InstanceCall2Opt, A_D); | 1738 BYTECODE(InstanceCall2Opt, A_D); |
1773 | 1739 |
1774 { | 1740 { |
1775 const uint16_t argc = rA; | 1741 const uint16_t argc = rA; |
1776 const uint16_t kidx = rD; | 1742 const uint16_t kidx = rD; |
1777 | 1743 |
1778 RawObject** call_base = SP - argc + 1; | 1744 RawObject** call_base = SP - argc + 1; |
1779 RawObject** call_top = SP + 1; | 1745 RawObject** call_top = SP + 1; |
1780 | 1746 |
1781 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); | 1747 RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); |
1782 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); | 1748 SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP)); |
1783 InstanceCall2(thread, icdata, call_base, call_top, | 1749 InstanceCall2(thread, icdata, call_base, call_top, &argdesc, &pp, &pc, |
1784 &argdesc, &pp, &pc, &FP, &SP, | 1750 &FP, &SP, true /* optimized */); |
1785 true /* optimized */); | |
1786 } | 1751 } |
1787 | 1752 |
1788 DISPATCH(); | 1753 DISPATCH(); |
1789 } | 1754 } |
1790 | 1755 |
1791 { | 1756 { |
1792 BYTECODE(PushPolymorphicInstanceCall, A_D); | 1757 BYTECODE(PushPolymorphicInstanceCall, A_D); |
1793 const uint8_t argc = rA; | 1758 const uint8_t argc = rA; |
1794 const intptr_t cids_length = rD; | 1759 const intptr_t cids_length = rD; |
1795 RawObject** args = SP - argc + 1; | 1760 RawObject** args = SP - argc + 1; |
1796 const intptr_t receiver_cid = SimulatorHelpers::GetClassId(args[0]); | 1761 const intptr_t receiver_cid = SimulatorHelpers::GetClassId(args[0]); |
1797 for (intptr_t i = 0; i < 2*cids_length; i+=2) { | 1762 for (intptr_t i = 0; i < 2 * cids_length; i += 2) { |
1798 const intptr_t icdata_cid = Bytecode::DecodeD(*(pc + i)); | 1763 const intptr_t icdata_cid = Bytecode::DecodeD(*(pc + i)); |
1799 if (receiver_cid == icdata_cid) { | 1764 if (receiver_cid == icdata_cid) { |
1800 RawFunction* target = | 1765 RawFunction* target = |
1801 RAW_CAST(Function, LOAD_CONSTANT(Bytecode::DecodeD(*(pc + i + 1)))); | 1766 RAW_CAST(Function, LOAD_CONSTANT(Bytecode::DecodeD(*(pc + i + 1)))); |
1802 *++SP = target; | 1767 *++SP = target; |
1803 pc++; | 1768 pc++; |
1804 break; | 1769 break; |
1805 } | 1770 } |
1806 } | 1771 } |
1807 pc += 2 * cids_length; | 1772 pc += 2 * cids_length; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1973 } | 1938 } |
1974 } | 1939 } |
1975 DISPATCH(); | 1940 DISPATCH(); |
1976 } | 1941 } |
1977 | 1942 |
1978 { | 1943 { |
1979 BYTECODE(Mod, A_B_C); | 1944 BYTECODE(Mod, A_B_C); |
1980 const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]); | 1945 const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]); |
1981 if (rhs != 0) { | 1946 if (rhs != 0) { |
1982 const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]); | 1947 const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]); |
1983 const intptr_t res = | 1948 const intptr_t res = ((lhs >> kSmiTagSize) % (rhs >> kSmiTagSize)) |
1984 ((lhs >> kSmiTagSize) % (rhs >> kSmiTagSize)) << kSmiTagSize; | 1949 << kSmiTagSize; |
1985 *reinterpret_cast<intptr_t*>(&FP[rA]) = | 1950 *reinterpret_cast<intptr_t*>(&FP[rA]) = |
1986 (res < 0) ? ((rhs < 0) ? (res - rhs) : (res + rhs)) : res; | 1951 (res < 0) ? ((rhs < 0) ? (res - rhs) : (res + rhs)) : res; |
1987 pc++; | 1952 pc++; |
1988 } | 1953 } |
1989 DISPATCH(); | 1954 DISPATCH(); |
1990 } | 1955 } |
1991 | 1956 |
1992 { | 1957 { |
1993 BYTECODE(Shl, A_B_C); | 1958 BYTECODE(Shl, A_B_C); |
1994 const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]) >> kSmiTagSize; | 1959 const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]) >> kSmiTagSize; |
1995 if (static_cast<uintptr_t>(rhs) < kBitsPerWord) { | 1960 if (static_cast<uintptr_t>(rhs) < kBitsPerWord) { |
1996 const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]); | 1961 const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]); |
1997 const intptr_t res = lhs << rhs; | 1962 const intptr_t res = lhs << rhs; |
1998 if (lhs == (res >> rhs)) { | 1963 if (lhs == (res >> rhs)) { |
1999 *reinterpret_cast<intptr_t*>(&FP[rA]) = res; | 1964 *reinterpret_cast<intptr_t*>(&FP[rA]) = res; |
2000 pc++; | 1965 pc++; |
2001 } | 1966 } |
2002 } | 1967 } |
2003 DISPATCH(); | 1968 DISPATCH(); |
2004 } | 1969 } |
2005 | 1970 |
2006 { | 1971 { |
2007 BYTECODE(Shr, A_B_C); | 1972 BYTECODE(Shr, A_B_C); |
2008 const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]) >> kSmiTagSize; | 1973 const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]) >> kSmiTagSize; |
2009 if (rhs >= 0) { | 1974 if (rhs >= 0) { |
2010 const intptr_t shift_amount = | 1975 const intptr_t shift_amount = |
2011 (rhs >= kBitsPerWord) ? (kBitsPerWord - 1) : rhs; | 1976 (rhs >= kBitsPerWord) ? (kBitsPerWord - 1) : rhs; |
2012 const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]) >> kSmiTagSize; | 1977 const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]) >> kSmiTagSize; |
2013 *reinterpret_cast<intptr_t*>(&FP[rA]) = | 1978 *reinterpret_cast<intptr_t*>(&FP[rA]) = (lhs >> shift_amount) |
2014 (lhs >> shift_amount) << kSmiTagSize; | 1979 << kSmiTagSize; |
2015 pc++; | 1980 pc++; |
2016 } | 1981 } |
2017 DISPATCH(); | 1982 DISPATCH(); |
2018 } | 1983 } |
2019 | 1984 |
2020 { | 1985 { |
2021 BYTECODE(ShlImm, A_B_C); | 1986 BYTECODE(ShlImm, A_B_C); |
2022 const uint8_t shift = rC; | 1987 const uint8_t shift = rC; |
2023 const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]); | 1988 const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]); |
2024 FP[rA] = reinterpret_cast<RawObject*>(lhs << shift); | 1989 FP[rA] = reinterpret_cast<RawObject*>(lhs << shift); |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2358 } | 2323 } |
2359 | 2324 |
2360 { | 2325 { |
2361 BYTECODE(BoxUint32, A_D); | 2326 BYTECODE(BoxUint32, A_D); |
2362 // Casts to zero out high 32 bits. | 2327 // Casts to zero out high 32 bits. |
2363 const uintptr_t value = reinterpret_cast<uintptr_t>(FP[rD]); | 2328 const uintptr_t value = reinterpret_cast<uintptr_t>(FP[rD]); |
2364 const uint32_t value32 = static_cast<uint32_t>(value); | 2329 const uint32_t value32 = static_cast<uint32_t>(value); |
2365 FP[rA] = Smi::New(static_cast<intptr_t>(value32)); | 2330 FP[rA] = Smi::New(static_cast<intptr_t>(value32)); |
2366 DISPATCH(); | 2331 DISPATCH(); |
2367 } | 2332 } |
2368 #else // defined(ARCH_IS_64_BIT) | 2333 #else // defined(ARCH_IS_64_BIT) |
2369 { | 2334 { |
2370 BYTECODE(WriteIntoDouble, A_D); | 2335 BYTECODE(WriteIntoDouble, A_D); |
2371 UNIMPLEMENTED(); | 2336 UNIMPLEMENTED(); |
2372 DISPATCH(); | 2337 DISPATCH(); |
2373 } | 2338 } |
2374 | 2339 |
2375 { | 2340 { |
2376 BYTECODE(UnboxDouble, A_D); | 2341 BYTECODE(UnboxDouble, A_D); |
2377 UNIMPLEMENTED(); | 2342 UNIMPLEMENTED(); |
2378 DISPATCH(); | 2343 DISPATCH(); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2583 DISPATCH(); | 2548 DISPATCH(); |
2584 } | 2549 } |
2585 goto ReturnImpl; | 2550 goto ReturnImpl; |
2586 | 2551 |
2587 BYTECODE(Return, A); | 2552 BYTECODE(Return, A); |
2588 result = FP[rA]; | 2553 result = FP[rA]; |
2589 goto ReturnImpl; | 2554 goto ReturnImpl; |
2590 | 2555 |
2591 BYTECODE(ReturnTOS, 0); | 2556 BYTECODE(ReturnTOS, 0); |
2592 result = *SP; | 2557 result = *SP; |
2593 // Fall through to the ReturnImpl. | 2558 // Fall through to the ReturnImpl. |
2594 | 2559 |
2595 ReturnImpl: | 2560 ReturnImpl: |
2596 // Restore caller PC. | 2561 // Restore caller PC. |
2597 pc = SavedCallerPC(FP); | 2562 pc = SavedCallerPC(FP); |
2598 pc_ = reinterpret_cast<uword>(pc); // For the profiler. | 2563 pc_ = reinterpret_cast<uword>(pc); // For the profiler. |
2599 | 2564 |
2600 // Check if it is a fake PC marking the entry frame. | 2565 // Check if it is a fake PC marking the entry frame. |
2601 if ((reinterpret_cast<uword>(pc) & 2) != 0) { | 2566 if ((reinterpret_cast<uword>(pc) & 2) != 0) { |
2602 const intptr_t argc = reinterpret_cast<uword>(pc) >> 2; | 2567 const intptr_t argc = reinterpret_cast<uword>(pc) >> 2; |
2603 fp_ = sp_ = | 2568 fp_ = sp_ = |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2725 } | 2690 } |
2726 DISPATCH(); | 2691 DISPATCH(); |
2727 } | 2692 } |
2728 | 2693 |
2729 // TODO(vegorov) allocation bytecodes can benefit from the new-space | 2694 // TODO(vegorov) allocation bytecodes can benefit from the new-space |
2730 // allocation fast-path that does not transition into the runtime system. | 2695 // allocation fast-path that does not transition into the runtime system. |
2731 { | 2696 { |
2732 BYTECODE(AllocateUninitializedContext, A_D); | 2697 BYTECODE(AllocateUninitializedContext, A_D); |
2733 const uint16_t num_context_variables = rD; | 2698 const uint16_t num_context_variables = rD; |
2734 const intptr_t instance_size = Context::InstanceSize(num_context_variables); | 2699 const intptr_t instance_size = Context::InstanceSize(num_context_variables); |
2735 const uword start = | 2700 const uword start = thread->heap()->new_space()->TryAllocate(instance_size); |
2736 thread->heap()->new_space()->TryAllocate(instance_size); | |
2737 if (LIKELY(start != 0)) { | 2701 if (LIKELY(start != 0)) { |
2738 uword tags = 0; | 2702 uword tags = 0; |
2739 tags = RawObject::ClassIdTag::update(kContextCid, tags); | 2703 tags = RawObject::ClassIdTag::update(kContextCid, tags); |
2740 tags = RawObject::SizeTag::update(instance_size, tags); | 2704 tags = RawObject::SizeTag::update(instance_size, tags); |
2741 *reinterpret_cast<uword*>(start + Array::tags_offset()) = tags; | 2705 *reinterpret_cast<uword*>(start + Array::tags_offset()) = tags; |
2742 *reinterpret_cast<uword*>(start + Context::num_variables_offset()) = | 2706 *reinterpret_cast<uword*>(start + Context::num_variables_offset()) = |
2743 num_context_variables; | 2707 num_context_variables; |
2744 FP[rA] = reinterpret_cast<RawObject*>(start + kHeapObjectTag); | 2708 FP[rA] = reinterpret_cast<RawObject*>(start + kHeapObjectTag); |
2745 pc += 2; | 2709 pc += 2; |
2746 } | 2710 } |
(...skipping 26 matching lines...) Expand all Loading... |
2773 | 2737 |
2774 { | 2738 { |
2775 BYTECODE(AllocateOpt, A_D); | 2739 BYTECODE(AllocateOpt, A_D); |
2776 const uword tags = | 2740 const uword tags = |
2777 static_cast<uword>(Smi::Value(RAW_CAST(Smi, LOAD_CONSTANT(rD)))); | 2741 static_cast<uword>(Smi::Value(RAW_CAST(Smi, LOAD_CONSTANT(rD)))); |
2778 const intptr_t instance_size = RawObject::SizeTag::decode(tags); | 2742 const intptr_t instance_size = RawObject::SizeTag::decode(tags); |
2779 const uword start = thread->heap()->new_space()->TryAllocate(instance_size); | 2743 const uword start = thread->heap()->new_space()->TryAllocate(instance_size); |
2780 if (LIKELY(start != 0)) { | 2744 if (LIKELY(start != 0)) { |
2781 *reinterpret_cast<uword*>(start + Instance::tags_offset()) = tags; | 2745 *reinterpret_cast<uword*>(start + Instance::tags_offset()) = tags; |
2782 for (intptr_t current_offset = sizeof(RawInstance); | 2746 for (intptr_t current_offset = sizeof(RawInstance); |
2783 current_offset < instance_size; | 2747 current_offset < instance_size; current_offset += kWordSize) { |
2784 current_offset += kWordSize) { | |
2785 *reinterpret_cast<RawObject**>(start + current_offset) = null_value; | 2748 *reinterpret_cast<RawObject**>(start + current_offset) = null_value; |
2786 } | 2749 } |
2787 FP[rA] = reinterpret_cast<RawObject*>(start + kHeapObjectTag); | 2750 FP[rA] = reinterpret_cast<RawObject*>(start + kHeapObjectTag); |
2788 pc += 2; | 2751 pc += 2; |
2789 } | 2752 } |
2790 DISPATCH(); | 2753 DISPATCH(); |
2791 } | 2754 } |
2792 | 2755 |
2793 { | 2756 { |
2794 BYTECODE(Allocate, A_D); | 2757 BYTECODE(Allocate, A_D); |
2795 SP[1] = 0; // Space for the result. | 2758 SP[1] = 0; // Space for the result. |
2796 SP[2] = LOAD_CONSTANT(rD); // Class object. | 2759 SP[2] = LOAD_CONSTANT(rD); // Class object. |
2797 SP[3] = null_value; // Type arguments. | 2760 SP[3] = null_value; // Type arguments. |
2798 Exit(thread, FP, SP + 4, pc); | 2761 Exit(thread, FP, SP + 4, pc); |
2799 NativeArguments args(thread, 2, SP + 2, SP + 1); | 2762 NativeArguments args(thread, 2, SP + 2, SP + 1); |
2800 INVOKE_RUNTIME(DRT_AllocateObject, args); | 2763 INVOKE_RUNTIME(DRT_AllocateObject, args); |
2801 SP++; // Result is in SP[1]. | 2764 SP++; // Result is in SP[1]. |
2802 DISPATCH(); | 2765 DISPATCH(); |
2803 } | 2766 } |
2804 | 2767 |
2805 { | 2768 { |
2806 BYTECODE(AllocateTOpt, A_D); | 2769 BYTECODE(AllocateTOpt, A_D); |
2807 const uword tags = Smi::Value(RAW_CAST(Smi, LOAD_CONSTANT(rD))); | 2770 const uword tags = Smi::Value(RAW_CAST(Smi, LOAD_CONSTANT(rD))); |
2808 const intptr_t instance_size = RawObject::SizeTag::decode(tags); | 2771 const intptr_t instance_size = RawObject::SizeTag::decode(tags); |
2809 const uword start = thread->heap()->new_space()->TryAllocate(instance_size); | 2772 const uword start = thread->heap()->new_space()->TryAllocate(instance_size); |
2810 if (LIKELY(start != 0)) { | 2773 if (LIKELY(start != 0)) { |
2811 RawObject* type_args = SP[0]; | 2774 RawObject* type_args = SP[0]; |
2812 const intptr_t type_args_offset = Bytecode::DecodeD(*pc); | 2775 const intptr_t type_args_offset = Bytecode::DecodeD(*pc); |
2813 *reinterpret_cast<uword*>(start + Instance::tags_offset()) = tags; | 2776 *reinterpret_cast<uword*>(start + Instance::tags_offset()) = tags; |
2814 for (intptr_t current_offset = sizeof(RawInstance); | 2777 for (intptr_t current_offset = sizeof(RawInstance); |
2815 current_offset < instance_size; | 2778 current_offset < instance_size; current_offset += kWordSize) { |
2816 current_offset += kWordSize) { | |
2817 *reinterpret_cast<RawObject**>(start + current_offset) = null_value; | 2779 *reinterpret_cast<RawObject**>(start + current_offset) = null_value; |
2818 } | 2780 } |
2819 *reinterpret_cast<RawObject**>(start + type_args_offset) = type_args; | 2781 *reinterpret_cast<RawObject**>(start + type_args_offset) = type_args; |
2820 FP[rA] = reinterpret_cast<RawObject*>(start + kHeapObjectTag); | 2782 FP[rA] = reinterpret_cast<RawObject*>(start + kHeapObjectTag); |
2821 SP -= 1; // Consume the type arguments on the stack. | 2783 SP -= 1; // Consume the type arguments on the stack. |
2822 pc += 4; | 2784 pc += 4; |
2823 } | 2785 } |
2824 DISPATCH(); | 2786 DISPATCH(); |
2825 } | 2787 } |
2826 | 2788 |
2827 { | 2789 { |
2828 BYTECODE(AllocateT, 0); | 2790 BYTECODE(AllocateT, 0); |
2829 SP[1] = SP[-0]; // Class object. | 2791 SP[1] = SP[-0]; // Class object. |
2830 SP[2] = SP[-1]; // Type arguments | 2792 SP[2] = SP[-1]; // Type arguments |
2831 Exit(thread, FP, SP + 3, pc); | 2793 Exit(thread, FP, SP + 3, pc); |
2832 NativeArguments args(thread, 2, SP + 1, SP - 1); | 2794 NativeArguments args(thread, 2, SP + 1, SP - 1); |
2833 INVOKE_RUNTIME(DRT_AllocateObject, args); | 2795 INVOKE_RUNTIME(DRT_AllocateObject, args); |
2834 SP -= 1; // Result is in SP - 1. | 2796 SP -= 1; // Result is in SP - 1. |
2835 DISPATCH(); | 2797 DISPATCH(); |
2836 } | 2798 } |
2837 | 2799 |
2838 { | 2800 { |
2839 BYTECODE(CreateArrayOpt, A_B_C); | 2801 BYTECODE(CreateArrayOpt, A_B_C); |
2840 const intptr_t length = Smi::Value(RAW_CAST(Smi, FP[rB])); | 2802 const intptr_t length = Smi::Value(RAW_CAST(Smi, FP[rB])); |
2841 if (LIKELY(length <= Array::kMaxElements)) { | 2803 if (LIKELY(length <= Array::kMaxElements)) { |
2842 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; | 2804 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; |
2843 const intptr_t instance_size = | 2805 const intptr_t instance_size = |
2844 (fixed_size + length*kWordSize) & ~(kObjectAlignment - 1); | 2806 (fixed_size + length * kWordSize) & ~(kObjectAlignment - 1); |
2845 const uword start = | 2807 const uword start = |
2846 thread->heap()->new_space()->TryAllocate(instance_size); | 2808 thread->heap()->new_space()->TryAllocate(instance_size); |
2847 if (LIKELY(start != 0)) { | 2809 if (LIKELY(start != 0)) { |
2848 const intptr_t cid = kArrayCid; | 2810 const intptr_t cid = kArrayCid; |
2849 uword tags = 0; | 2811 uword tags = 0; |
2850 if (LIKELY(instance_size < RawObject::SizeTag::kMaxSizeTag)) { | 2812 if (LIKELY(instance_size < RawObject::SizeTag::kMaxSizeTag)) { |
2851 tags = RawObject::SizeTag::update(instance_size, tags); | 2813 tags = RawObject::SizeTag::update(instance_size, tags); |
2852 } | 2814 } |
2853 tags = RawObject::ClassIdTag::update(cid, tags); | 2815 tags = RawObject::ClassIdTag::update(cid, tags); |
2854 *reinterpret_cast<uword*>(start + Instance::tags_offset()) = tags; | 2816 *reinterpret_cast<uword*>(start + Instance::tags_offset()) = tags; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2892 RawTypeArguments* instance_type_arguments = | 2854 RawTypeArguments* instance_type_arguments = |
2893 static_cast<RawTypeArguments*>(null_value); | 2855 static_cast<RawTypeArguments*>(null_value); |
2894 RawObject* instance_cid_or_function; | 2856 RawObject* instance_cid_or_function; |
2895 if (cid == kClosureCid) { | 2857 if (cid == kClosureCid) { |
2896 RawClosure* closure = static_cast<RawClosure*>(instance); | 2858 RawClosure* closure = static_cast<RawClosure*>(instance); |
2897 instance_type_arguments = closure->ptr()->type_arguments_; | 2859 instance_type_arguments = closure->ptr()->type_arguments_; |
2898 instance_cid_or_function = closure->ptr()->function_; | 2860 instance_cid_or_function = closure->ptr()->function_; |
2899 } else { | 2861 } else { |
2900 instance_cid_or_function = Smi::New(cid); | 2862 instance_cid_or_function = Smi::New(cid); |
2901 | 2863 |
2902 RawClass* instance_class = | 2864 RawClass* instance_class = thread->isolate()->class_table()->At(cid); |
2903 thread->isolate()->class_table()->At(cid); | |
2904 if (instance_class->ptr()->num_type_arguments_ < 0) { | 2865 if (instance_class->ptr()->num_type_arguments_ < 0) { |
2905 goto InstanceOfCallRuntime; | 2866 goto InstanceOfCallRuntime; |
2906 } else if (instance_class->ptr()->num_type_arguments_ > 0) { | 2867 } else if (instance_class->ptr()->num_type_arguments_ > 0) { |
2907 instance_type_arguments = reinterpret_cast<RawTypeArguments**>( | 2868 instance_type_arguments = reinterpret_cast<RawTypeArguments**>( |
2908 instance | 2869 instance->ptr())[instance_class->ptr() |
2909 ->ptr())[instance_class->ptr() | 2870 ->type_arguments_field_offset_in_words_]; |
2910 ->type_arguments_field_offset_in_words_]; | |
2911 } | 2871 } |
2912 } | 2872 } |
2913 | 2873 |
2914 for (RawObject** entries = cache->ptr()->cache_->ptr()->data(); | 2874 for (RawObject** entries = cache->ptr()->cache_->ptr()->data(); |
2915 entries[0] != null_value; | 2875 entries[0] != null_value; |
2916 entries += SubtypeTestCache::kTestEntryLength) { | 2876 entries += SubtypeTestCache::kTestEntryLength) { |
2917 if ((entries[SubtypeTestCache::kInstanceClassIdOrFunction] == | 2877 if ((entries[SubtypeTestCache::kInstanceClassIdOrFunction] == |
2918 instance_cid_or_function) && | 2878 instance_cid_or_function) && |
2919 (entries[SubtypeTestCache::kInstanceTypeArguments] == | 2879 (entries[SubtypeTestCache::kInstanceTypeArguments] == |
2920 instance_type_arguments) && | 2880 instance_type_arguments) && |
2921 (entries[SubtypeTestCache::kInstantiatorTypeArguments] == | 2881 (entries[SubtypeTestCache::kInstantiatorTypeArguments] == |
2922 instantiator_type_arguments)) { | 2882 instantiator_type_arguments)) { |
2923 SP[-3] = entries[SubtypeTestCache::kTestResult]; | 2883 SP[-3] = entries[SubtypeTestCache::kTestResult]; |
2924 goto InstanceOfOk; | 2884 goto InstanceOfOk; |
2925 } | 2885 } |
2926 } | 2886 } |
2927 } | 2887 } |
2928 | 2888 |
| 2889 // clang-format off |
2929 InstanceOfCallRuntime: | 2890 InstanceOfCallRuntime: |
2930 { | 2891 { |
2931 SP[1] = instance; | 2892 SP[1] = instance; |
2932 SP[2] = type; | 2893 SP[2] = type; |
2933 SP[3] = instantiator_type_arguments; | 2894 SP[3] = instantiator_type_arguments; |
2934 SP[4] = cache; | 2895 SP[4] = cache; |
2935 Exit(thread, FP, SP + 5, pc); | 2896 Exit(thread, FP, SP + 5, pc); |
2936 NativeArguments native_args(thread, 4, SP + 1, SP - 3); | 2897 NativeArguments native_args(thread, 4, SP + 1, SP - 3); |
2937 INVOKE_RUNTIME(DRT_Instanceof, native_args); | 2898 INVOKE_RUNTIME(DRT_Instanceof, native_args); |
2938 } | 2899 } |
| 2900 // clang-format on |
2939 | 2901 |
2940 InstanceOfOk: | 2902 InstanceOfOk: |
2941 SP -= 3; | 2903 SP -= 3; |
2942 if (rA) { // Negate result. | 2904 if (rA) { // Negate result. |
2943 SP[0] = (SP[0] == true_value) ? false_value : true_value; | 2905 SP[0] = (SP[0] == true_value) ? false_value : true_value; |
2944 } | 2906 } |
2945 DISPATCH(); | 2907 DISPATCH(); |
2946 } | 2908 } |
2947 | 2909 |
2948 { | 2910 { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2981 RawTypeArguments* instance_type_arguments = | 2943 RawTypeArguments* instance_type_arguments = |
2982 static_cast<RawTypeArguments*>(null_value); | 2944 static_cast<RawTypeArguments*>(null_value); |
2983 RawObject* instance_cid_or_function; | 2945 RawObject* instance_cid_or_function; |
2984 if (cid == kClosureCid) { | 2946 if (cid == kClosureCid) { |
2985 RawClosure* closure = static_cast<RawClosure*>(instance); | 2947 RawClosure* closure = static_cast<RawClosure*>(instance); |
2986 instance_type_arguments = closure->ptr()->type_arguments_; | 2948 instance_type_arguments = closure->ptr()->type_arguments_; |
2987 instance_cid_or_function = closure->ptr()->function_; | 2949 instance_cid_or_function = closure->ptr()->function_; |
2988 } else { | 2950 } else { |
2989 instance_cid_or_function = Smi::New(cid); | 2951 instance_cid_or_function = Smi::New(cid); |
2990 | 2952 |
2991 RawClass* instance_class = | 2953 RawClass* instance_class = thread->isolate()->class_table()->At(cid); |
2992 thread->isolate()->class_table()->At(cid); | |
2993 if (instance_class->ptr()->num_type_arguments_ < 0) { | 2954 if (instance_class->ptr()->num_type_arguments_ < 0) { |
2994 goto AssertAssignableCallRuntime; | 2955 goto AssertAssignableCallRuntime; |
2995 } else if (instance_class->ptr()->num_type_arguments_ > 0) { | 2956 } else if (instance_class->ptr()->num_type_arguments_ > 0) { |
2996 instance_type_arguments = reinterpret_cast<RawTypeArguments**>( | 2957 instance_type_arguments = reinterpret_cast<RawTypeArguments**>( |
2997 instance | 2958 instance->ptr())[instance_class->ptr() |
2998 ->ptr())[instance_class->ptr() | 2959 ->type_arguments_field_offset_in_words_]; |
2999 ->type_arguments_field_offset_in_words_]; | |
3000 } | 2960 } |
3001 } | 2961 } |
3002 | 2962 |
3003 for (RawObject** entries = cache->ptr()->cache_->ptr()->data(); | 2963 for (RawObject** entries = cache->ptr()->cache_->ptr()->data(); |
3004 entries[0] != null_value; | 2964 entries[0] != null_value; |
3005 entries += SubtypeTestCache::kTestEntryLength) { | 2965 entries += SubtypeTestCache::kTestEntryLength) { |
3006 if ((entries[SubtypeTestCache::kInstanceClassIdOrFunction] == | 2966 if ((entries[SubtypeTestCache::kInstanceClassIdOrFunction] == |
3007 instance_cid_or_function) && | 2967 instance_cid_or_function) && |
3008 (entries[SubtypeTestCache::kInstanceTypeArguments] == | 2968 (entries[SubtypeTestCache::kInstanceTypeArguments] == |
3009 instance_type_arguments) && | 2969 instance_type_arguments) && |
3010 (entries[SubtypeTestCache::kInstantiatorTypeArguments] == | 2970 (entries[SubtypeTestCache::kInstantiatorTypeArguments] == |
3011 instantiator_type_arguments)) { | 2971 instantiator_type_arguments)) { |
3012 if (true_value == entries[SubtypeTestCache::kTestResult]) { | 2972 if (true_value == entries[SubtypeTestCache::kTestResult]) { |
3013 goto AssertAssignableOk; | 2973 goto AssertAssignableOk; |
3014 } else { | 2974 } else { |
3015 break; | 2975 break; |
3016 } | 2976 } |
3017 } | 2977 } |
3018 } | 2978 } |
3019 } | 2979 } |
3020 | 2980 |
3021 AssertAssignableCallRuntime: | 2981 AssertAssignableCallRuntime: |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3353 DISPATCH(); | 3313 DISPATCH(); |
3354 } | 3314 } |
3355 | 3315 |
3356 { | 3316 { |
3357 BYTECODE(IfDGt, A_D); | 3317 BYTECODE(IfDGt, A_D); |
3358 const double lhs = bit_cast<double, RawObject*>(FP[rA]); | 3318 const double lhs = bit_cast<double, RawObject*>(FP[rA]); |
3359 const double rhs = bit_cast<double, RawObject*>(FP[rD]); | 3319 const double rhs = bit_cast<double, RawObject*>(FP[rD]); |
3360 pc += (lhs > rhs) ? 0 : 1; | 3320 pc += (lhs > rhs) ? 0 : 1; |
3361 DISPATCH(); | 3321 DISPATCH(); |
3362 } | 3322 } |
3363 #else // defined(ARCH_IS_64_BIT) | 3323 #else // defined(ARCH_IS_64_BIT) |
3364 { | 3324 { |
3365 BYTECODE(IfDEq, A_D); | 3325 BYTECODE(IfDEq, A_D); |
3366 UNREACHABLE(); | 3326 UNREACHABLE(); |
3367 DISPATCH(); | 3327 DISPATCH(); |
3368 } | 3328 } |
3369 | 3329 |
3370 { | 3330 { |
3371 BYTECODE(IfDNe, A_D); | 3331 BYTECODE(IfDNe, A_D); |
3372 UNREACHABLE(); | 3332 UNREACHABLE(); |
3373 DISPATCH(); | 3333 DISPATCH(); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3670 ClosureNoSuchMethod: | 3630 ClosureNoSuchMethod: |
3671 #if defined(DEBUG) | 3631 #if defined(DEBUG) |
3672 function_h ^= FrameFunction(FP); | 3632 function_h ^= FrameFunction(FP); |
3673 ASSERT(function_h.IsClosureFunction()); | 3633 ASSERT(function_h.IsClosureFunction()); |
3674 #endif | 3634 #endif |
3675 | 3635 |
3676 // Restore caller context as we are going to throw NoSuchMethod. | 3636 // Restore caller context as we are going to throw NoSuchMethod. |
3677 pc = SavedCallerPC(FP); | 3637 pc = SavedCallerPC(FP); |
3678 | 3638 |
3679 const bool has_dart_caller = (reinterpret_cast<uword>(pc) & 2) == 0; | 3639 const bool has_dart_caller = (reinterpret_cast<uword>(pc) & 2) == 0; |
3680 const intptr_t argc = has_dart_caller | 3640 const intptr_t argc = has_dart_caller ? Bytecode::DecodeArgc(pc[-1]) |
3681 ? Bytecode::DecodeArgc(pc[-1]) | 3641 : (reinterpret_cast<uword>(pc) >> 2); |
3682 : (reinterpret_cast<uword>(pc) >> 2); | |
3683 | 3642 |
3684 SP = FrameArguments(FP, 0); | 3643 SP = FrameArguments(FP, 0); |
3685 RawObject** args = SP - argc; | 3644 RawObject** args = SP - argc; |
3686 FP = SavedCallerFP(FP); | 3645 FP = SavedCallerFP(FP); |
3687 if (has_dart_caller) { | 3646 if (has_dart_caller) { |
3688 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); | 3647 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); |
3689 } | 3648 } |
3690 | 3649 |
3691 *++SP = null_value; | 3650 *++SP = null_value; |
3692 *++SP = args[0]; // Closure object. | 3651 *++SP = args[0]; // Closure object. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3763 pc_ = pc; | 3722 pc_ = pc; |
3764 special_[kExceptionSpecialIndex] = raw_exception; | 3723 special_[kExceptionSpecialIndex] = raw_exception; |
3765 special_[kStacktraceSpecialIndex] = raw_stacktrace; | 3724 special_[kStacktraceSpecialIndex] = raw_stacktrace; |
3766 buf->Longjmp(); | 3725 buf->Longjmp(); |
3767 UNREACHABLE(); | 3726 UNREACHABLE(); |
3768 } | 3727 } |
3769 | 3728 |
3770 } // namespace dart | 3729 } // namespace dart |
3771 | 3730 |
3772 #endif // defined TARGET_ARCH_DBC | 3731 #endif // defined TARGET_ARCH_DBC |
OLD | NEW |