| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 // The intrinsic code below is executed before a method has built its frame. | 5 // The intrinsic code below is executed before a method has built its frame. |
| 6 // The return address is on the stack and the arguments below it. | 6 // The return address is on the stack and the arguments below it. |
| 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. | 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. |
| 8 // Each intrinsification method returns true if the corresponding | 8 // Each intrinsification method returns true if the corresponding |
| 9 // Dart method was intrinsified. | 9 // Dart method was intrinsified. |
| 10 | 10 |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 __ j(EQUAL, &checked_ok, Assembler::kNearJump); | 202 __ j(EQUAL, &checked_ok, Assembler::kNearJump); |
| 203 | 203 |
| 204 __ movl(EBX, Address(ESP, + 3 * kWordSize)); // Array. | 204 __ movl(EBX, Address(ESP, + 3 * kWordSize)); // Array. |
| 205 __ movl(EBX, FieldAddress(EBX, type_args_field_offset)); | 205 __ movl(EBX, FieldAddress(EBX, type_args_field_offset)); |
| 206 // EBX: Type arguments of array. | 206 // EBX: Type arguments of array. |
| 207 __ cmpl(EBX, raw_null); | 207 __ cmpl(EBX, raw_null); |
| 208 __ j(EQUAL, &checked_ok, Assembler::kNearJump); | 208 __ j(EQUAL, &checked_ok, Assembler::kNearJump); |
| 209 // Check if it's dynamic. | 209 // Check if it's dynamic. |
| 210 // For now handle only TypeArguments and bail out if InstantiatedTypeArgs. | 210 // For now handle only TypeArguments and bail out if InstantiatedTypeArgs. |
| 211 __ CompareClassId(EBX, kTypeArgumentsCid, EAX); | 211 __ CompareClassId(EBX, kTypeArgumentsCid, EAX); |
| 212 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); | 212 __ j(NOT_EQUAL, &fall_through); |
| 213 // Get type at index 0. | 213 // Get type at index 0. |
| 214 __ movl(EAX, FieldAddress(EBX, TypeArguments::type_at_offset(0))); | 214 __ movl(EAX, FieldAddress(EBX, TypeArguments::type_at_offset(0))); |
| 215 __ CompareObject(EAX, Type::ZoneHandle(Type::DynamicType())); | 215 __ CompareObject(EAX, Type::ZoneHandle(Type::DynamicType())); |
| 216 __ j(EQUAL, &checked_ok, Assembler::kNearJump); | 216 __ j(EQUAL, &checked_ok, Assembler::kNearJump); |
| 217 // Check for int and num. | 217 // Check for int and num. |
| 218 __ testl(EDI, Immediate(kSmiTagMask)); // Value is Smi? | 218 __ testl(EDI, Immediate(kSmiTagMask)); // Value is Smi? |
| 219 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi value. | 219 __ j(NOT_ZERO, &fall_through); // Non-smi value. |
| 220 __ CompareObject(EAX, Type::ZoneHandle(Type::IntType())); | 220 __ CompareObject(EAX, Type::ZoneHandle(Type::IntType())); |
| 221 __ j(EQUAL, &checked_ok, Assembler::kNearJump); | 221 __ j(EQUAL, &checked_ok, Assembler::kNearJump); |
| 222 __ CompareObject(EAX, Type::ZoneHandle(Type::Number())); | 222 __ CompareObject(EAX, Type::ZoneHandle(Type::Number())); |
| 223 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); | 223 __ j(NOT_EQUAL, &fall_through); |
| 224 __ Bind(&checked_ok); | 224 __ Bind(&checked_ok); |
| 225 } | 225 } |
| 226 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. | 226 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. |
| 227 __ testl(EBX, Immediate(kSmiTagMask)); | 227 __ testl(EBX, Immediate(kSmiTagMask)); |
| 228 // Index not Smi. | 228 // Index not Smi. |
| 229 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); | 229 __ j(NOT_ZERO, &fall_through); |
| 230 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // Array. | 230 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // Array. |
| 231 // Range check. | 231 // Range check. |
| 232 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); | 232 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); |
| 233 // Runtime throws exception. | 233 // Runtime throws exception. |
| 234 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 234 __ j(ABOVE_EQUAL, &fall_through); |
| 235 // Note that EBX is Smi, i.e, times 2. | 235 // Note that EBX is Smi, i.e, times 2. |
| 236 ASSERT(kSmiTagShift == 1); | 236 ASSERT(kSmiTagShift == 1); |
| 237 // Destroy ECX as we will not continue in the function. | 237 // Destroy ECX as we will not continue in the function. |
| 238 __ movl(ECX, Address(ESP, + 1 * kWordSize)); // Value. | 238 __ movl(ECX, Address(ESP, + 1 * kWordSize)); // Value. |
| 239 __ StoreIntoObject(EAX, | 239 __ StoreIntoObject(EAX, |
| 240 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()), | 240 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()), |
| 241 ECX); | 241 ECX); |
| 242 // Caller is responsible of preserving the value if necessary. | 242 // Caller is responsible of preserving the value if necessary. |
| 243 __ ret(); | 243 __ ret(); |
| 244 __ Bind(&fall_through); | 244 __ Bind(&fall_through); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 264 Isolate* isolate = Isolate::Current(); | 264 Isolate* isolate = Isolate::Current(); |
| 265 Heap* heap = isolate->heap(); | 265 Heap* heap = isolate->heap(); |
| 266 | 266 |
| 267 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 267 __ movl(EAX, Address::Absolute(heap->TopAddress())); |
| 268 __ leal(EBX, Address(EAX, fixed_size)); | 268 __ leal(EBX, Address(EAX, fixed_size)); |
| 269 | 269 |
| 270 // Check if the allocation fits into the remaining space. | 270 // Check if the allocation fits into the remaining space. |
| 271 // EAX: potential new backing array object start. | 271 // EAX: potential new backing array object start. |
| 272 // EBX: potential next object start. | 272 // EBX: potential next object start. |
| 273 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); | 273 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); |
| 274 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 274 __ j(ABOVE_EQUAL, &fall_through); |
| 275 | 275 |
| 276 // Successfully allocated the object(s), now update top to point to | 276 // Successfully allocated the object(s), now update top to point to |
| 277 // next object start and initialize the object. | 277 // next object start and initialize the object. |
| 278 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 278 __ movl(Address::Absolute(heap->TopAddress()), EBX); |
| 279 __ addl(EAX, Immediate(kHeapObjectTag)); | 279 __ addl(EAX, Immediate(kHeapObjectTag)); |
| 280 | 280 |
| 281 // Initialize the tags. | 281 // Initialize the tags. |
| 282 // EAX: new growable array object start as a tagged pointer. | 282 // EAX: new growable array object start as a tagged pointer. |
| 283 const Class& cls = Class::Handle( | 283 const Class& cls = Class::Handle( |
| 284 isolate->object_store()->growable_object_array_class()); | 284 isolate->object_store()->growable_object_array_class()); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 // Set value into growable object array at specified index. | 359 // Set value into growable object array at specified index. |
| 360 // On stack: growable array (+3), index (+2), value (+1), return-address (+0). | 360 // On stack: growable array (+3), index (+2), value (+1), return-address (+0). |
| 361 bool Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) { | 361 bool Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) { |
| 362 if (FLAG_enable_type_checks) { | 362 if (FLAG_enable_type_checks) { |
| 363 return false; | 363 return false; |
| 364 } | 364 } |
| 365 Label fall_through; | 365 Label fall_through; |
| 366 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. | 366 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. |
| 367 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray. | 367 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray. |
| 368 __ testl(EBX, Immediate(kSmiTagMask)); | 368 __ testl(EBX, Immediate(kSmiTagMask)); |
| 369 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 369 __ j(NOT_ZERO, &fall_through); // Non-smi index. |
| 370 // Range check using _length field. | 370 // Range check using _length field. |
| 371 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); | 371 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); |
| 372 // Runtime throws exception. | 372 // Runtime throws exception. |
| 373 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 373 __ j(ABOVE_EQUAL, &fall_through); |
| 374 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. | 374 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. |
| 375 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value. | 375 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value. |
| 376 // Note that EBX is Smi, i.e, times 2. | 376 // Note that EBX is Smi, i.e, times 2. |
| 377 ASSERT(kSmiTagShift == 1); | 377 ASSERT(kSmiTagShift == 1); |
| 378 __ StoreIntoObject(EAX, | 378 __ StoreIntoObject(EAX, |
| 379 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()), | 379 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()), |
| 380 EDI); | 380 EDI); |
| 381 __ ret(); | 381 __ ret(); |
| 382 __ Bind(&fall_through); | 382 __ Bind(&fall_through); |
| 383 return false; | 383 return false; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 405 // Set data of growable object array. | 405 // Set data of growable object array. |
| 406 // On stack: growable array (+2), data (+1), return-address (+0). | 406 // On stack: growable array (+2), data (+1), return-address (+0). |
| 407 bool Intrinsifier::GrowableArray_setData(Assembler* assembler) { | 407 bool Intrinsifier::GrowableArray_setData(Assembler* assembler) { |
| 408 if (FLAG_enable_type_checks) { | 408 if (FLAG_enable_type_checks) { |
| 409 return false; | 409 return false; |
| 410 } | 410 } |
| 411 Label fall_through; | 411 Label fall_through; |
| 412 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Data. | 412 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Data. |
| 413 // Check that data is an ObjectArray. | 413 // Check that data is an ObjectArray. |
| 414 __ testl(EBX, Immediate(kSmiTagMask)); | 414 __ testl(EBX, Immediate(kSmiTagMask)); |
| 415 __ j(ZERO, &fall_through, Assembler::kNearJump); // Data is Smi. | 415 __ j(ZERO, &fall_through); // Data is Smi. |
| 416 __ CompareClassId(EBX, kArrayCid, EAX); | 416 __ CompareClassId(EBX, kArrayCid, EAX); |
| 417 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); | 417 __ j(NOT_EQUAL, &fall_through); |
| 418 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array. | 418 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array. |
| 419 __ StoreIntoObject(EAX, | 419 __ StoreIntoObject(EAX, |
| 420 FieldAddress(EAX, GrowableObjectArray::data_offset()), | 420 FieldAddress(EAX, GrowableObjectArray::data_offset()), |
| 421 EBX); | 421 EBX); |
| 422 __ ret(); | 422 __ ret(); |
| 423 __ Bind(&fall_through); | 423 __ Bind(&fall_through); |
| 424 return false; | 424 return false; |
| 425 } | 425 } |
| 426 | 426 |
| 427 | 427 |
| 428 // Add an element to growable array if it doesn't need to grow, otherwise | 428 // Add an element to growable array if it doesn't need to grow, otherwise |
| 429 // call into regular code. | 429 // call into regular code. |
| 430 // On stack: growable array (+2), value (+1), return-address (+0). | 430 // On stack: growable array (+2), value (+1), return-address (+0). |
| 431 bool Intrinsifier::GrowableArray_add(Assembler* assembler) { | 431 bool Intrinsifier::GrowableArray_add(Assembler* assembler) { |
| 432 // In checked mode we need to type-check the incoming argument. | 432 // In checked mode we need to type-check the incoming argument. |
| 433 if (FLAG_enable_type_checks) return false; | 433 if (FLAG_enable_type_checks) return false; |
| 434 Label fall_through; | 434 Label fall_through; |
| 435 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. | 435 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. |
| 436 __ movl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); | 436 __ movl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); |
| 437 // EBX: length. | 437 // EBX: length. |
| 438 __ movl(EDI, FieldAddress(EAX, GrowableObjectArray::data_offset())); | 438 __ movl(EDI, FieldAddress(EAX, GrowableObjectArray::data_offset())); |
| 439 // EDI: data. | 439 // EDI: data. |
| 440 // Compare length with capacity. | 440 // Compare length with capacity. |
| 441 __ cmpl(EBX, FieldAddress(EDI, Array::length_offset())); | 441 __ cmpl(EBX, FieldAddress(EDI, Array::length_offset())); |
| 442 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Must grow data. | 442 __ j(EQUAL, &fall_through); // Must grow data. |
| 443 const Immediate& value_one = | 443 const Immediate& value_one = |
| 444 Immediate(reinterpret_cast<int32_t>(Smi::New(1))); | 444 Immediate(reinterpret_cast<int32_t>(Smi::New(1))); |
| 445 // len = len + 1; | 445 // len = len + 1; |
| 446 __ addl(FieldAddress(EAX, GrowableObjectArray::length_offset()), value_one); | 446 __ addl(FieldAddress(EAX, GrowableObjectArray::length_offset()), value_one); |
| 447 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Value | 447 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Value |
| 448 ASSERT(kSmiTagShift == 1); | 448 ASSERT(kSmiTagShift == 1); |
| 449 __ StoreIntoObject(EDI, | 449 __ StoreIntoObject(EDI, |
| 450 FieldAddress(EDI, EBX, TIMES_2, Array::data_offset()), | 450 FieldAddress(EDI, EBX, TIMES_2, Array::data_offset()), |
| 451 EAX); | 451 EAX); |
| 452 const Immediate& raw_null = | 452 const Immediate& raw_null = |
| (...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1495 __ SmiTag(EAX); | 1495 __ SmiTag(EAX); |
| 1496 __ movl(FieldAddress(EBX, String::hash_offset()), EAX); | 1496 __ movl(FieldAddress(EBX, String::hash_offset()), EAX); |
| 1497 __ ret(); | 1497 __ ret(); |
| 1498 return true; | 1498 return true; |
| 1499 } | 1499 } |
| 1500 | 1500 |
| 1501 #undef __ | 1501 #undef __ |
| 1502 } // namespace dart | 1502 } // namespace dart |
| 1503 | 1503 |
| 1504 #endif // defined TARGET_ARCH_IA32 | 1504 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |