1 #ifdef USE_PRAGMA_IDENT_SRC
   2 #pragma ident "@(#)icache_x86.cpp       1.22 07/09/17 09:33:47 JVM"
   3 #endif
   4 /*
   5  * Copyright 1997-2004 Sun Microsystems, Inc.  All Rights Reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  23  * CA 95054 USA or visit www.sun.com if you need additional information or
  24  * have any questions.
  25  *  
  26  */
  27 
  28 #include "incls/_precompiled.incl"
  29 #include "incls/_icache_x86.cpp.incl"
  30 
  31 #define __ _masm->
  32 
  33 void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flush_icache_stub) {
  34   StubCodeMark mark(this, "ICache", "flush_icache_stub");
  35 
  36   address start = __ pc();
  37 #ifdef AMD64
  38 
  39   const Register addr  = c_rarg0;
  40   const Register lines = c_rarg1;
  41   const Register magic = c_rarg2;
  42 
  43   Label flush_line, done;
  44 
  45   __ testl(lines, lines);
  46   __ jcc(Assembler::zero, done);
  47 
  48   // Force ordering wrt cflush.
  49   // Other fence and sync instructions won't do the job.
  50   __ mfence();
  51 
  52   __ bind(flush_line);
  53   __ clflush(Address(addr, 0));
  54   __ addq(addr, ICache::line_size);
  55   __ decrementl(lines);
  56   __ jcc(Assembler::notZero, flush_line);
  57 
  58   __ mfence();
  59 
  60   __ bind(done);
  61 
  62 #else
  63   const Address magic(rsp, 3*wordSize);
  64   __ lock(); __ addl(Address(rsp, 0), 0);
  65 #endif // AMD64
  66   __ movl(rax, magic); // Handshake with caller to make sure it happened!
  67   __ ret(0);
  68 
  69   // Must be set here so StubCodeMark destructor can call the flush stub.
  70   *flush_icache_stub = (ICache::flush_icache_stub_t)start;
  71 }
  72 
  73 #undef __