Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/stubGenerator_x86_32.cpp @ 647:bd441136a5ce
Merge
author | kvn |
---|---|
date | Thu, 19 Mar 2009 09:13:24 -0700 |
parents | 0fbdb4381b99 c517646eef23 |
children | e5b0439ef4ae |
comparison
equal
deleted
inserted
replaced
640:ba50942c8138 | 647:bd441136a5ce |
---|---|
1308 // The temp is killed. | 1308 // The temp is killed. |
1309 void generate_type_check(Register sub_klass, | 1309 void generate_type_check(Register sub_klass, |
1310 Address& super_check_offset_addr, | 1310 Address& super_check_offset_addr, |
1311 Address& super_klass_addr, | 1311 Address& super_klass_addr, |
1312 Register temp, | 1312 Register temp, |
1313 Label* L_success_ptr, Label* L_failure_ptr) { | 1313 Label* L_success, Label* L_failure) { |
1314 BLOCK_COMMENT("type_check:"); | 1314 BLOCK_COMMENT("type_check:"); |
1315 | 1315 |
1316 Label L_fallthrough; | 1316 Label L_fallthrough; |
1317 bool fall_through_on_success = (L_success_ptr == NULL); | 1317 #define LOCAL_JCC(assembler_con, label_ptr) \ |
1318 if (fall_through_on_success) { | 1318 if (label_ptr != NULL) __ jcc(assembler_con, *(label_ptr)); \ |
1319 L_success_ptr = &L_fallthrough; | 1319 else __ jcc(assembler_con, L_fallthrough) /*omit semi*/ |
1320 } else { | 1320 |
1321 L_failure_ptr = &L_fallthrough; | 1321 // The following is a strange variation of the fast path which requires |
1322 } | 1322 // one less register, because needed values are on the argument stack. |
1323 Label& L_success = *L_success_ptr; | 1323 // __ check_klass_subtype_fast_path(sub_klass, *super_klass*, temp, |
1324 Label& L_failure = *L_failure_ptr; | 1324 // L_success, L_failure, NULL); |
1325 | |
1326 assert_different_registers(sub_klass, temp); | 1325 assert_different_registers(sub_klass, temp); |
1327 | 1326 |
1328 // a couple of useful fields in sub_klass: | |
1329 int ss_offset = (klassOopDesc::header_size() * HeapWordSize + | |
1330 Klass::secondary_supers_offset_in_bytes()); | |
1331 int sc_offset = (klassOopDesc::header_size() * HeapWordSize + | 1327 int sc_offset = (klassOopDesc::header_size() * HeapWordSize + |
1332 Klass::secondary_super_cache_offset_in_bytes()); | 1328 Klass::secondary_super_cache_offset_in_bytes()); |
1333 Address secondary_supers_addr(sub_klass, ss_offset); | |
1334 Address super_cache_addr( sub_klass, sc_offset); | |
1335 | 1329 |
1336 // if the pointers are equal, we are done (e.g., String[] elements) | 1330 // if the pointers are equal, we are done (e.g., String[] elements) |
1337 __ cmpptr(sub_klass, super_klass_addr); | 1331 __ cmpptr(sub_klass, super_klass_addr); |
1338 __ jcc(Assembler::equal, L_success); | 1332 LOCAL_JCC(Assembler::equal, L_success); |
1339 | 1333 |
1340 // check the supertype display: | 1334 // check the supertype display: |
1341 __ movl2ptr(temp, super_check_offset_addr); | 1335 __ movl2ptr(temp, super_check_offset_addr); |
1342 Address super_check_addr(sub_klass, temp, Address::times_1, 0); | 1336 Address super_check_addr(sub_klass, temp, Address::times_1, 0); |
1343 __ movptr(temp, super_check_addr); // load displayed supertype | 1337 __ movptr(temp, super_check_addr); // load displayed supertype |
1344 __ cmpptr(temp, super_klass_addr); // test the super type | 1338 __ cmpptr(temp, super_klass_addr); // test the super type |
1345 __ jcc(Assembler::equal, L_success); | 1339 LOCAL_JCC(Assembler::equal, L_success); |
1346 | 1340 |
1347 // if it was a primary super, we can just fail immediately | 1341 // if it was a primary super, we can just fail immediately |
1348 __ cmpl(super_check_offset_addr, sc_offset); | 1342 __ cmpl(super_check_offset_addr, sc_offset); |
1349 __ jcc(Assembler::notEqual, L_failure); | 1343 LOCAL_JCC(Assembler::notEqual, L_failure); |
1350 | 1344 |
1351 // Now do a linear scan of the secondary super-klass chain. | 1345 // The repne_scan instruction uses fixed registers, which will get spilled. |
1352 // This code is rarely used, so simplicity is a virtue here. | 1346 // We happen to know this works best when super_klass is in rax. |
1353 inc_counter_np(SharedRuntime::_partial_subtype_ctr); | 1347 Register super_klass = temp; |
1354 { | 1348 __ movptr(super_klass, super_klass_addr); |
1355 // The repne_scan instruction uses fixed registers, which we must spill. | 1349 __ check_klass_subtype_slow_path(sub_klass, super_klass, noreg, noreg, |
1356 // (We need a couple more temps in any case.) | 1350 L_success, L_failure); |
1357 __ push(rax); | 1351 |
1358 __ push(rcx); | |
1359 __ push(rdi); | |
1360 assert_different_registers(sub_klass, rax, rcx, rdi); | |
1361 | |
1362 __ movptr(rdi, secondary_supers_addr); | |
1363 // Load the array length. | |
1364 __ movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes())); | |
1365 // Skip to start of data. | |
1366 __ addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); | |
1367 // Scan rcx words at [edi] for occurance of rax, | |
1368 // Set NZ/Z based on last compare | |
1369 __ movptr(rax, super_klass_addr); | |
1370 __ repne_scan(); | |
1371 | |
1372 // Unspill the temp. registers: | |
1373 __ pop(rdi); | |
1374 __ pop(rcx); | |
1375 __ pop(rax); | |
1376 } | |
1377 __ jcc(Assembler::notEqual, L_failure); | |
1378 | |
1379 // Success. Cache the super we found and proceed in triumph. | |
1380 __ movptr(temp, super_klass_addr); // note: rax, is dead | |
1381 __ movptr(super_cache_addr, temp); | |
1382 | |
1383 if (!fall_through_on_success) | |
1384 __ jmp(L_success); | |
1385 | |
1386 // Fall through on failure! | |
1387 __ bind(L_fallthrough); | 1352 __ bind(L_fallthrough); |
1353 | |
1354 if (L_success == NULL) { BLOCK_COMMENT("L_success:"); } | |
1355 if (L_failure == NULL) { BLOCK_COMMENT("L_failure:"); } | |
1356 | |
1357 #undef LOCAL_JCC | |
1388 } | 1358 } |
1389 | 1359 |
1390 // | 1360 // |
1391 // Generate checkcasting array copy stub | 1361 // Generate checkcasting array copy stub |
1392 // | 1362 // |