1 /* 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_VM_RUNTIME_ICACHE_HPP 26 #define SHARE_VM_RUNTIME_ICACHE_HPP 27 28 #include "memory/allocation.hpp" 29 #include "runtime/stubCodeGenerator.hpp" 30 31 // Interface for updating the instruction cache. Whenever the VM modifies 32 // code, part of the processor instruction cache potentially has to be flushed. 33 34 // Default implementation is in icache.cpp, and can be hidden per-platform. 35 // Most platforms must provide only ICacheStubGenerator::generate_icache_flush(). 36 // Platforms that don't require icache flushing can just nullify the public 37 // members of AbstractICache in their ICache class. AbstractICache should never 38 // be referenced other than by deriving the ICache class from it. 39 // 40 // The code for the ICache class and for generate_icache_flush() must be in 41 // architecture-specific files, i.e., icache_<arch>.hpp/.cpp 42 43 class AbstractICache : AllStatic { 44 public: 45 // The flush stub signature 46 typedef int (*flush_icache_stub_t)(address addr, int lines, int magic); 47 48 protected: 49 // The flush stub function address 50 static flush_icache_stub_t _flush_icache_stub; 51 52 // Call the flush stub 53 static void call_flush_stub(address start, int lines); 54 55 public: 56 enum { 57 stub_size = 0, // Size of the icache flush stub in bytes 58 line_size = 0, // Icache line size in bytes 59 log2_line_size = 0 // log2(line_size) 60 }; 61 62 static void initialize(); 63 static void invalidate_word(address addr); 64 static void invalidate_range(address start, int nbytes); 65 }; 66 67 68 // Must be included before the definition of ICacheStubGenerator 69 // because ICacheStubGenerator uses ICache definitions. 70 71 #ifdef TARGET_ARCH_x86 72 # include "icache_x86.hpp" 73 #endif 74 #ifdef TARGET_ARCH_sparc 75 # include "icache_sparc.hpp" 76 #endif 77 #ifdef TARGET_ARCH_zero 78 # include "icache_zero.hpp" 79 #endif 80 #ifdef TARGET_ARCH_arm 81 # include "icache_arm.hpp" 82 #endif 83 #ifdef TARGET_ARCH_ppc 84 # include "icache_ppc.hpp" 85 #endif 86 #ifdef TARGET_ARCH_aarch64 87 # include "icache_aarch64.hpp" 88 #endif 89 90 91 92 class ICacheStubGenerator : public StubCodeGenerator { 93 public: 94 ICacheStubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {} 95 96 // Generate the icache flush stub. 97 // 98 // Since we cannot flush the cache when this stub is generated, 99 // it must be generated first, and just to be sure, we do extra 100 // work to allow a check that these instructions got executed. 101 // 102 // The flush stub has three parameters (see flush_icache_stub_t). 103 // 104 // addr - Start address, must be aligned at log2_line_size 105 // lines - Number of line_size icache lines to flush 106 // magic - Magic number copied to result register to make sure 107 // the stub executed properly 108 // 109 // A template for generate_icache_flush is 110 // 111 // #define __ _masm-> 112 // 113 // void ICacheStubGenerator::generate_icache_flush( 114 // ICache::flush_icache_stub_t* flush_icache_stub 115 // ) { 116 // StubCodeMark mark(this, "ICache", "flush_icache_stub"); 117 // 118 // address start = __ pc(); 119 // 120 // // emit flush stub asm code 121 // 122 // // Must be set here so StubCodeMark destructor can call the flush stub. 123 // *flush_icache_stub = (ICache::flush_icache_stub_t)start; 124 // }; 125 // 126 // #undef __ 127 // 128 // The first use of flush_icache_stub must apply it to itself. The 129 // StubCodeMark destructor in generate_icache_flush will call Assembler::flush, 130 // which in turn will call invalidate_range (see asm/assembler.cpp), which 131 // in turn will call the flush stub *before* generate_icache_flush returns. 132 // The usual method of having generate_icache_flush return the address of the 133 // stub to its caller, which would then, e.g., store that address in 134 // flush_icache_stub, won't work. generate_icache_flush must itself set 135 // flush_icache_stub to the address of the stub it generates before 136 // the StubCodeMark destructor is invoked. 137 138 void generate_icache_flush(ICache::flush_icache_stub_t* flush_icache_stub); 139 }; 140 141 #endif // SHARE_VM_RUNTIME_ICACHE_HPP