src/cpu/ppc/vm/ppc.ad
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/cpu/ppc/vm

src/cpu/ppc/vm/ppc.ad

Print this page
rev 6133 : [mq]: newstackbang-reviews
   1 //
   2 // Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   3 // Copyright 2012, 2013 SAP AG. All rights reserved.
   4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5 //
   6 // This code is free software; you can redistribute it and/or modify it
   7 // under the terms of the GNU General Public License version 2 only, as
   8 // published by the Free Software Foundation.
   9 //
  10 // This code is distributed in the hope that it will be useful, but WITHOUT
  11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13 // version 2 for more details (a copy is included in the LICENSE file that
  14 // accompanied this code).
  15 //
  16 // You should have received a copy of the GNU General Public License version
  17 // 2 along with this work; if not, write to the Free Software Foundation,
  18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19 //
  20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21 // or visit www.oracle.com if you need additional information or have any
  22 // questions.
  23 //


1319                   C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \
1320                 _masm.
1321 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling())                    \
1322                   C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none)
1323 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling())                 \
1324                   C->hb_scheduling()->_pdScheduling->advance_offset
1325 #else
1326 #define ___(op) if (UsePower6SchedulerPPC64)                                          \
1327                   Unimplemented();                                                    \
1328                 _masm.
1329 #define ___stop if (UsePower6SchedulerPPC64)                                          \
1330                   Unimplemented()
1331 #define ___advance if (UsePower6SchedulerPPC64)                                       \
1332                   Unimplemented()
1333 #endif
1334 
1335 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1336   Compile* C = ra_->C;
1337   MacroAssembler _masm(&cbuf);
1338 
1339   const long framesize = ((long)C->frame_slots()) << LogBytesPerInt;
1340   assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment");
1341 
1342   const bool method_is_frameless      = false /* TODO: PPC port C->is_frameless_method()*/;
1343 
1344   const Register return_pc            = R20; // Must match return_addr() in frame section.
1345   const Register callers_sp           = R21;
1346   const Register push_frame_temp      = R22;
1347   const Register toc_temp             = R23;
1348   assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp);
1349 
1350   if (method_is_frameless) {
1351     // Add nop at beginning of all frameless methods to prevent any
1352     // oop instructions from getting overwritten by make_not_entrant
1353     // (patching attempt would fail).
1354     ___(nop) nop();
1355   } else {
1356     // Get return pc.
1357     ___(mflr) mflr(return_pc);
1358   }
1359 
1360   // Calls to C2R adapters often do not accept exceptional returns.
1361   // We require that their callers must bang for them. But be
1362   // careful, because some VM calls (such as call site linkage) can
1363   // use several kilobytes of stack. But the stack safety zone should
1364   // account for that. See bugs 4446381, 4468289, 4497237.
1365   if (C->need_stack_bang(framesize) && UseStackBanging) {



1366     // Unfortunately we cannot use the function provided in
1367     // assembler.cpp as we have to emulate the pipes. So I had to
1368     // insert the code of generate_stack_overflow_check(), see
1369     // assembler.cpp for some illuminative comments.
1370     const int page_size = os::vm_page_size();
1371     int bang_end = StackShadowPages*page_size;
1372 
1373     // This is how far the previous frame's stack banging extended.
1374     const int bang_end_safe = bang_end;
1375 
1376     if (framesize > page_size) {
1377       bang_end += framesize;
1378     }
1379 
1380     int bang_offset = bang_end_safe;
1381 
1382     while (bang_offset <= bang_end) {
1383       // Need at least one stack bang at end of shadow zone.
1384 
1385       // Again I had to copy code, this time from assembler_ppc64.cpp,
1386       // bang_stack_with_offset - see there for comments.
1387 
1388       // Stack grows down, caller passes positive offset.
1389       assert(bang_offset > 0, "must bang with positive offset");
1390 
1391       long stdoffset = -bang_offset;
1392 
1393       if (Assembler::is_simm(stdoffset, 16)) {
1394         // Signed 16 bit offset, a simple std is ok.
1395         if (UseLoadInstructionsForStackBangingPPC64) {
1396           ___(ld) ld(R0,  (int)(signed short)stdoffset, R1_SP);
1397         } else {


1403         const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset);
1404 
1405         Register tmp = R11;
1406         ___(addis) addis(tmp, R1_SP, hi);
1407         if (UseLoadInstructionsForStackBangingPPC64) {
1408           ___(ld) ld(R0, lo, tmp);
1409         } else {
1410           ___(std) std(R0, lo, tmp);
1411         }
1412       } else {
1413         ShouldNotReachHere();
1414       }
1415 
1416       bang_offset += page_size;
1417     }
1418     // R11 trashed
1419   } // C->need_stack_bang(framesize) && UseStackBanging
1420 
1421   unsigned int bytes = (unsigned int)framesize;
1422   long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes);
1423   ciMethod *currMethod = C -> method();
1424 
1425   // Optimized version for most common case.
1426   if (UsePower6SchedulerPPC64 &&
1427       !method_is_frameless && Assembler::is_simm((int)(-offset), 16) &&
1428       !(false /* ConstantsALot TODO: PPC port*/)) {
1429     ___(or) mr(callers_sp, R1_SP);
1430     ___(std) std(return_pc, _abi(lr), R1_SP);
1431     ___(stdu) stdu(R1_SP, -offset, R1_SP);
1432     return;
1433   }
1434 
1435   if (!method_is_frameless) {
1436     // Get callers sp.
1437     ___(or) mr(callers_sp, R1_SP);
1438 
1439     // Push method's frame, modifies SP.
1440     assert(Assembler::is_uimm(framesize, 32U), "wrong type");
1441     // The ABI is already accounted for in 'framesize' via the
1442     // 'out_preserve' area.
1443     Register tmp = push_frame_temp;


   1 //
   2 // Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
   3 // Copyright 2012, 2014 SAP AG. All rights reserved.
   4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5 //
   6 // This code is free software; you can redistribute it and/or modify it
   7 // under the terms of the GNU General Public License version 2 only, as
   8 // published by the Free Software Foundation.
   9 //
  10 // This code is distributed in the hope that it will be useful, but WITHOUT
  11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13 // version 2 for more details (a copy is included in the LICENSE file that
  14 // accompanied this code).
  15 //
  16 // You should have received a copy of the GNU General Public License version
  17 // 2 along with this work; if not, write to the Free Software Foundation,
  18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19 //
  20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21 // or visit www.oracle.com if you need additional information or have any
  22 // questions.
  23 //


1319                   C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \
1320                 _masm.
1321 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling())                    \
1322                   C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none)
1323 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling())                 \
1324                   C->hb_scheduling()->_pdScheduling->advance_offset
1325 #else
1326 #define ___(op) if (UsePower6SchedulerPPC64)                                          \
1327                   Unimplemented();                                                    \
1328                 _masm.
1329 #define ___stop if (UsePower6SchedulerPPC64)                                          \
1330                   Unimplemented()
1331 #define ___advance if (UsePower6SchedulerPPC64)                                       \
1332                   Unimplemented()
1333 #endif
1334 
1335 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1336   Compile* C = ra_->C;
1337   MacroAssembler _masm(&cbuf);
1338 
1339   const long framesize = C->frame_size_in_bytes();
1340   assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment");
1341 
1342   const bool method_is_frameless      = false /* TODO: PPC port C->is_frameless_method()*/;
1343 
1344   const Register return_pc            = R20; // Must match return_addr() in frame section.
1345   const Register callers_sp           = R21;
1346   const Register push_frame_temp      = R22;
1347   const Register toc_temp             = R23;
1348   assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp);
1349 
1350   if (method_is_frameless) {
1351     // Add nop at beginning of all frameless methods to prevent any
1352     // oop instructions from getting overwritten by make_not_entrant
1353     // (patching attempt would fail).
1354     ___(nop) nop();
1355   } else {
1356     // Get return pc.
1357     ___(mflr) mflr(return_pc);
1358   }
1359 
1360   // Calls to C2R adapters often do not accept exceptional returns.
1361   // We require that their callers must bang for them. But be
1362   // careful, because some VM calls (such as call site linkage) can
1363   // use several kilobytes of stack. But the stack safety zone should
1364   // account for that. See bugs 4446381, 4468289, 4497237.
1365 
1366   int bangsize = C->bang_size_in_bytes();
1367   assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect");
1368   if (C->need_stack_bang(bangsize) && UseStackBanging) {
1369     // Unfortunately we cannot use the function provided in
1370     // assembler.cpp as we have to emulate the pipes. So I had to
1371     // insert the code of generate_stack_overflow_check(), see
1372     // assembler.cpp for some illuminative comments.
1373     const int page_size = os::vm_page_size();
1374     int bang_end = (StackShadowPages+1) * page_size;
1375 
1376     // This is how far the previous frame's stack banging extended.
1377     const int bang_end_safe = bang_end;
1378 
1379     if (bangsize > page_size) {
1380       bang_end += bangsize;
1381     }
1382 
1383     int bang_offset = bang_end_safe;
1384 
1385     while (bang_offset <= bang_end) {
1386       // Need at least one stack bang at end of shadow zone.
1387 
1388       // Again I had to copy code, this time from assembler_ppc64.cpp,
1389       // bang_stack_with_offset - see there for comments.
1390 
1391       // Stack grows down, caller passes positive offset.
1392       assert(bang_offset > 0, "must bang with positive offset");
1393 
1394       long stdoffset = -bang_offset;
1395 
1396       if (Assembler::is_simm(stdoffset, 16)) {
1397         // Signed 16 bit offset, a simple std is ok.
1398         if (UseLoadInstructionsForStackBangingPPC64) {
1399           ___(ld) ld(R0,  (int)(signed short)stdoffset, R1_SP);
1400         } else {


1406         const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset);
1407 
1408         Register tmp = R11;
1409         ___(addis) addis(tmp, R1_SP, hi);
1410         if (UseLoadInstructionsForStackBangingPPC64) {
1411           ___(ld) ld(R0, lo, tmp);
1412         } else {
1413           ___(std) std(R0, lo, tmp);
1414         }
1415       } else {
1416         ShouldNotReachHere();
1417       }
1418 
1419       bang_offset += page_size;
1420     }
1421     // R11 trashed
1422   } // C->need_stack_bang(framesize) && UseStackBanging
1423 
1424   unsigned int bytes = (unsigned int)framesize;
1425   long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes);
1426   ciMethod *currMethod = C->method();
1427 
1428   // Optimized version for most common case.
1429   if (UsePower6SchedulerPPC64 &&
1430       !method_is_frameless && Assembler::is_simm((int)(-offset), 16) &&
1431       !(false /* ConstantsALot TODO: PPC port*/)) {
1432     ___(or) mr(callers_sp, R1_SP);
1433     ___(std) std(return_pc, _abi(lr), R1_SP);
1434     ___(stdu) stdu(R1_SP, -offset, R1_SP);
1435     return;
1436   }
1437 
1438   if (!method_is_frameless) {
1439     // Get callers sp.
1440     ___(or) mr(callers_sp, R1_SP);
1441 
1442     // Push method's frame, modifies SP.
1443     assert(Assembler::is_uimm(framesize, 32U), "wrong type");
1444     // The ABI is already accounted for in 'framesize' via the
1445     // 'out_preserve' area.
1446     Register tmp = push_frame_temp;


src/cpu/ppc/vm/ppc.ad
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File