src/cpu/x86/vm/stubGenerator_x86_32.cpp

changeset 1082
bd441136a5ce
parent 1014
0fbdb4381b99
parent 1079
c517646eef23
child 1145
e5b0439ef4ae
equal deleted inserted replaced
1075:ba50942c8138 1082: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 //

mercurial