| 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 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1369 if (emit_full_guard) { | 1369 if (emit_full_guard) { |
| 1370 __ LoadObject(field_reg, Field::ZoneHandle(field().raw()), PP); | 1370 __ LoadObject(field_reg, Field::ZoneHandle(field().raw()), PP); |
| 1371 | 1371 |
| 1372 FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset()); | 1372 FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset()); |
| 1373 FieldAddress field_nullability_operand( | 1373 FieldAddress field_nullability_operand( |
| 1374 field_reg, Field::is_nullable_offset()); | 1374 field_reg, Field::is_nullable_offset()); |
| 1375 | 1375 |
| 1376 if (value_cid == kDynamicCid) { | 1376 if (value_cid == kDynamicCid) { |
| 1377 LoadValueCid(compiler, value_cid_reg, value_reg); | 1377 LoadValueCid(compiler, value_cid_reg, value_reg); |
| 1378 | 1378 |
| 1379 __ cmpq(value_cid_reg, field_cid_operand); | 1379 __ cmpl(value_cid_reg, field_cid_operand); |
| 1380 __ j(EQUAL, &ok); | 1380 __ j(EQUAL, &ok); |
| 1381 __ cmpq(value_cid_reg, field_nullability_operand); | 1381 __ cmpl(value_cid_reg, field_nullability_operand); |
| 1382 } else if (value_cid == kNullCid) { | 1382 } else if (value_cid == kNullCid) { |
| 1383 __ CompareImmediate(field_nullability_operand, Immediate(value_cid), PP); | 1383 __ cmpl(field_nullability_operand, Immediate(value_cid)); |
| 1384 } else { | 1384 } else { |
| 1385 __ CompareImmediate(field_cid_operand, Immediate(value_cid), PP); | 1385 __ cmpl(field_cid_operand, Immediate(value_cid)); |
| 1386 } | 1386 } |
| 1387 __ j(EQUAL, &ok); | 1387 __ j(EQUAL, &ok); |
| 1388 | 1388 |
| 1389 // Check if the tracked state of the guarded field can be initialized | 1389 // Check if the tracked state of the guarded field can be initialized |
| 1390 // inline. If the field needs length check we fall through to runtime | 1390 // inline. If the field needs length check we fall through to runtime |
| 1391 // which is responsible for computing offset of the length field | 1391 // which is responsible for computing offset of the length field |
| 1392 // based on the class id. | 1392 // based on the class id. |
| 1393 if (!field().needs_length_check()) { | 1393 if (!field().needs_length_check()) { |
| 1394 // Uninitialized field can be handled inline. Check if the | 1394 // Uninitialized field can be handled inline. Check if the |
| 1395 // field is still unitialized. | 1395 // field is still unitialized. |
| 1396 __ CompareImmediate(field_cid_operand, Immediate(kIllegalCid), PP); | 1396 __ cmpl(field_cid_operand, Immediate(kIllegalCid)); |
| 1397 __ j(NOT_EQUAL, fail); | 1397 __ j(NOT_EQUAL, fail); |
| 1398 | 1398 |
| 1399 if (value_cid == kDynamicCid) { | 1399 if (value_cid == kDynamicCid) { |
| 1400 __ movq(field_cid_operand, value_cid_reg); | 1400 __ movl(field_cid_operand, value_cid_reg); |
| 1401 __ movq(field_nullability_operand, value_cid_reg); | 1401 __ movl(field_nullability_operand, value_cid_reg); |
| 1402 } else { | 1402 } else { |
| 1403 ASSERT(field_reg != kNoRegister); | 1403 ASSERT(field_reg != kNoRegister); |
| 1404 __ LoadImmediate(field_cid_operand, Immediate(value_cid), PP); | 1404 __ movl(field_cid_operand, Immediate(value_cid)); |
| 1405 __ LoadImmediate(field_nullability_operand, Immediate(value_cid), PP); | 1405 __ movl(field_nullability_operand, Immediate(value_cid)); |
| 1406 } | 1406 } |
| 1407 | 1407 |
| 1408 if (deopt == NULL) { | 1408 if (deopt == NULL) { |
| 1409 ASSERT(!compiler->is_optimizing()); | 1409 ASSERT(!compiler->is_optimizing()); |
| 1410 __ jmp(&ok); | 1410 __ jmp(&ok); |
| 1411 } | 1411 } |
| 1412 } | 1412 } |
| 1413 | 1413 |
| 1414 if (deopt == NULL) { | 1414 if (deopt == NULL) { |
| 1415 ASSERT(!compiler->is_optimizing()); | 1415 ASSERT(!compiler->is_optimizing()); |
| 1416 __ Bind(fail); | 1416 __ Bind(fail); |
| 1417 | 1417 |
| 1418 __ CompareImmediate(FieldAddress(field_reg, Field::guarded_cid_offset()), | 1418 __ cmpl(FieldAddress(field_reg, Field::guarded_cid_offset()), |
| 1419 Immediate(kDynamicCid), PP); | 1419 Immediate(kDynamicCid)); |
| 1420 __ j(EQUAL, &ok); | 1420 __ j(EQUAL, &ok); |
| 1421 | 1421 |
| 1422 __ pushq(field_reg); | 1422 __ pushq(field_reg); |
| 1423 __ pushq(value_reg); | 1423 __ pushq(value_reg); |
| 1424 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); | 1424 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); |
| 1425 __ Drop(2); // Drop the field and the value. | 1425 __ Drop(2); // Drop the field and the value. |
| 1426 } | 1426 } |
| 1427 } else { | 1427 } else { |
| 1428 ASSERT(compiler->is_optimizing()); | 1428 ASSERT(compiler->is_optimizing()); |
| 1429 ASSERT(deopt != NULL); | 1429 ASSERT(deopt != NULL); |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1678 Register temp2 = locs()->temp(1).reg(); | 1678 Register temp2 = locs()->temp(1).reg(); |
| 1679 FpuRegister fpu_temp = locs()->temp(2).fpu_reg(); | 1679 FpuRegister fpu_temp = locs()->temp(2).fpu_reg(); |
| 1680 | 1680 |
| 1681 Label store_pointer; | 1681 Label store_pointer; |
| 1682 Label store_double; | 1682 Label store_double; |
| 1683 Label store_float32x4; | 1683 Label store_float32x4; |
| 1684 Label store_float64x2; | 1684 Label store_float64x2; |
| 1685 | 1685 |
| 1686 __ LoadObject(temp, Field::ZoneHandle(field().raw()), PP); | 1686 __ LoadObject(temp, Field::ZoneHandle(field().raw()), PP); |
| 1687 | 1687 |
| 1688 __ cmpq(FieldAddress(temp, Field::is_nullable_offset()), | 1688 __ cmpl(FieldAddress(temp, Field::is_nullable_offset()), |
| 1689 Immediate(kNullCid)); | 1689 Immediate(kNullCid)); |
| 1690 __ j(EQUAL, &store_pointer); | 1690 __ j(EQUAL, &store_pointer); |
| 1691 | 1691 |
| 1692 __ movzxb(temp2, FieldAddress(temp, Field::kind_bits_offset())); | 1692 __ movzxb(temp2, FieldAddress(temp, Field::kind_bits_offset())); |
| 1693 __ testq(temp2, Immediate(1 << Field::kUnboxingCandidateBit)); | 1693 __ testq(temp2, Immediate(1 << Field::kUnboxingCandidateBit)); |
| 1694 __ j(ZERO, &store_pointer); | 1694 __ j(ZERO, &store_pointer); |
| 1695 | 1695 |
| 1696 __ cmpq(FieldAddress(temp, Field::guarded_cid_offset()), | 1696 __ cmpl(FieldAddress(temp, Field::guarded_cid_offset()), |
| 1697 Immediate(kDoubleCid)); | 1697 Immediate(kDoubleCid)); |
| 1698 __ j(EQUAL, &store_double); | 1698 __ j(EQUAL, &store_double); |
| 1699 | 1699 |
| 1700 __ cmpq(FieldAddress(temp, Field::guarded_cid_offset()), | 1700 __ cmpl(FieldAddress(temp, Field::guarded_cid_offset()), |
| 1701 Immediate(kFloat32x4Cid)); | 1701 Immediate(kFloat32x4Cid)); |
| 1702 __ j(EQUAL, &store_float32x4); | 1702 __ j(EQUAL, &store_float32x4); |
| 1703 | 1703 |
| 1704 __ cmpl(FieldAddress(temp, Field::guarded_cid_offset()), | 1704 __ cmpl(FieldAddress(temp, Field::guarded_cid_offset()), |
| 1705 Immediate(kFloat64x2Cid)); | 1705 Immediate(kFloat64x2Cid)); |
| 1706 __ j(EQUAL, &store_float64x2); | 1706 __ j(EQUAL, &store_float64x2); |
| 1707 | 1707 |
| 1708 // Fall through. | 1708 // Fall through. |
| 1709 __ jmp(&store_pointer); | 1709 __ jmp(&store_pointer); |
| 1710 | 1710 |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2180 Register temp = locs()->temp(1).reg(); | 2180 Register temp = locs()->temp(1).reg(); |
| 2181 XmmRegister value = locs()->temp(0).fpu_reg(); | 2181 XmmRegister value = locs()->temp(0).fpu_reg(); |
| 2182 | 2182 |
| 2183 Label load_pointer; | 2183 Label load_pointer; |
| 2184 Label load_double; | 2184 Label load_double; |
| 2185 Label load_float32x4; | 2185 Label load_float32x4; |
| 2186 Label load_float64x2; | 2186 Label load_float64x2; |
| 2187 | 2187 |
| 2188 __ LoadObject(result, Field::ZoneHandle(field()->raw()), PP); | 2188 __ LoadObject(result, Field::ZoneHandle(field()->raw()), PP); |
| 2189 | 2189 |
| 2190 __ cmpq(FieldAddress(result, Field::is_nullable_offset()), | 2190 __ cmpl(FieldAddress(result, Field::is_nullable_offset()), |
| 2191 Immediate(kNullCid)); | 2191 Immediate(kNullCid)); |
| 2192 __ j(EQUAL, &load_pointer); | 2192 __ j(EQUAL, &load_pointer); |
| 2193 | 2193 |
| 2194 __ cmpq(FieldAddress(result, Field::guarded_cid_offset()), | 2194 __ cmpl(FieldAddress(result, Field::guarded_cid_offset()), |
| 2195 Immediate(kDoubleCid)); | 2195 Immediate(kDoubleCid)); |
| 2196 __ j(EQUAL, &load_double); | 2196 __ j(EQUAL, &load_double); |
| 2197 | 2197 |
| 2198 __ cmpq(FieldAddress(result, Field::guarded_cid_offset()), | 2198 __ cmpl(FieldAddress(result, Field::guarded_cid_offset()), |
| 2199 Immediate(kFloat32x4Cid)); | 2199 Immediate(kFloat32x4Cid)); |
| 2200 __ j(EQUAL, &load_float32x4); | 2200 __ j(EQUAL, &load_float32x4); |
| 2201 | 2201 |
| 2202 __ cmpq(FieldAddress(result, Field::guarded_cid_offset()), | 2202 __ cmpl(FieldAddress(result, Field::guarded_cid_offset()), |
| 2203 Immediate(kFloat64x2Cid)); | 2203 Immediate(kFloat64x2Cid)); |
| 2204 __ j(EQUAL, &load_float64x2); | 2204 __ j(EQUAL, &load_float64x2); |
| 2205 | 2205 |
| 2206 // Fall through. | 2206 // Fall through. |
| 2207 __ jmp(&load_pointer); | 2207 __ jmp(&load_pointer); |
| 2208 | 2208 |
| 2209 if (!compiler->is_optimizing()) { | 2209 if (!compiler->is_optimizing()) { |
| 2210 locs()->live_registers()->Add(locs()->in(0)); | 2210 locs()->live_registers()->Add(locs()->in(0)); |
| 2211 } | 2211 } |
| 2212 | 2212 |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2535 // Generate stack overflow check. | 2535 // Generate stack overflow check. |
| 2536 __ LoadImmediate( | 2536 __ LoadImmediate( |
| 2537 temp, Immediate(Isolate::Current()->stack_limit_address()), PP); | 2537 temp, Immediate(Isolate::Current()->stack_limit_address()), PP); |
| 2538 __ cmpq(RSP, Address(temp, 0)); | 2538 __ cmpq(RSP, Address(temp, 0)); |
| 2539 __ j(BELOW_EQUAL, slow_path->entry_label()); | 2539 __ j(BELOW_EQUAL, slow_path->entry_label()); |
| 2540 if (compiler->CanOSRFunction() && in_loop()) { | 2540 if (compiler->CanOSRFunction() && in_loop()) { |
| 2541 // In unoptimized code check the usage counter to trigger OSR at loop | 2541 // In unoptimized code check the usage counter to trigger OSR at loop |
| 2542 // stack checks. Use progressively higher thresholds for more deeply | 2542 // stack checks. Use progressively higher thresholds for more deeply |
| 2543 // nested loops to attempt to hit outer loops with OSR when possible. | 2543 // nested loops to attempt to hit outer loops with OSR when possible. |
| 2544 __ LoadObject(temp, compiler->parsed_function().function(), PP); | 2544 __ LoadObject(temp, compiler->parsed_function().function(), PP); |
| 2545 intptr_t threshold = | 2545 int32_t threshold = |
| 2546 FLAG_optimization_counter_threshold * (loop_depth() + 1); | 2546 FLAG_optimization_counter_threshold * (loop_depth() + 1); |
| 2547 __ CompareImmediate(FieldAddress(temp, Function::usage_counter_offset()), | 2547 __ cmpl(FieldAddress(temp, Function::usage_counter_offset()), |
| 2548 Immediate(threshold), PP); | 2548 Immediate(threshold)); |
| 2549 __ j(GREATER_EQUAL, slow_path->osr_entry_label()); | 2549 __ j(GREATER_EQUAL, slow_path->osr_entry_label()); |
| 2550 } | 2550 } |
| 2551 if (compiler->ForceSlowPathForStackOverflow()) { | 2551 if (compiler->ForceSlowPathForStackOverflow()) { |
| 2552 __ jmp(slow_path->entry_label()); | 2552 __ jmp(slow_path->entry_label()); |
| 2553 } | 2553 } |
| 2554 __ Bind(slow_path->exit_label()); | 2554 __ Bind(slow_path->exit_label()); |
| 2555 } | 2555 } |
| 2556 | 2556 |
| 2557 | 2557 |
| 2558 static void EmitJavascriptOverflowCheck(FlowGraphCompiler* compiler, | 2558 static void EmitJavascriptOverflowCheck(FlowGraphCompiler* compiler, |
| (...skipping 3264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5823 PcDescriptors::kOther, | 5823 PcDescriptors::kOther, |
| 5824 locs()); | 5824 locs()); |
| 5825 __ Drop(ArgumentCount()); // Discard arguments. | 5825 __ Drop(ArgumentCount()); // Discard arguments. |
| 5826 } | 5826 } |
| 5827 | 5827 |
| 5828 } // namespace dart | 5828 } // namespace dart |
| 5829 | 5829 |
| 5830 #undef __ | 5830 #undef __ |
| 5831 | 5831 |
| 5832 #endif // defined TARGET_ARCH_X64 | 5832 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |