2323 */
2424
2525#include " asm/macroAssembler.hpp"
26+ #include " runtime/flags/flagSetting.hpp"
27+ #include " runtime/globals_extension.hpp"
2628#include " runtime/icache.hpp"
2729
2830#define __ _masm->
2931
32+ void x86_generate_icache_fence (MacroAssembler* _masm) {
33+ switch (X86ICacheSync) {
34+ case 0 :
35+ break ;
36+ case 1 :
37+ __ mfence ();
38+ break ;
39+ case 2 :
40+ case 3 :
41+ __ sfence ();
42+ break ;
43+ case 4 :
44+ __ push (rax);
45+ __ push (rbx);
46+ __ push (rcx);
47+ __ push (rdx);
48+ __ xorptr (rax, rax);
49+ __ cpuid ();
50+ __ pop (rdx);
51+ __ pop (rcx);
52+ __ pop (rbx);
53+ __ pop (rax);
54+ break ;
55+ case 5 :
56+ __ serialize ();
57+ break ;
58+ default :
59+ ShouldNotReachHere ();
60+ }
61+ }
62+
63+ void x86_generate_icache_flush_insn (MacroAssembler* _masm, Register addr) {
64+ switch (X86ICacheSync) {
65+ case 1 :
66+ __ clflush (Address (addr, 0 ));
67+ break ;
68+ case 2 :
69+ __ clflushopt (Address (addr, 0 ));
70+ break ;
71+ case 3 :
72+ __ clwb (Address (addr, 0 ));
73+ break ;
74+ default :
75+ ShouldNotReachHere ();
76+ }
77+ }
78+
3079void ICacheStubGenerator::generate_icache_flush (ICache::flush_icache_stub_t * flush_icache_stub) {
31- StubCodeMark mark (this , " ICache" , " flush_icache_stub " );
80+ StubCodeMark mark (this , " ICache" , _stub_name );
3281
3382 address start = __ pc ();
34- #ifdef AMD64
3583
3684 const Register addr = c_rarg0;
3785 const Register lines = c_rarg1;
@@ -40,31 +88,45 @@ void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flu
4088 Label flush_line, done;
4189
4290 __ testl (lines, lines);
43- __ jcc (Assembler::zero, done);
91+ __ jccb (Assembler::zero, done);
4492
45- // Force ordering wrt cflush.
46- // Other fence and sync instructions won't do the job.
47- __ mfence ();
93+ x86_generate_icache_fence (_masm);
4894
49- __ bind (flush_line);
50- __ clflush (Address (addr, 0 ));
51- __ addptr (addr, ICache::line_size);
52- __ decrementl (lines);
53- __ jcc (Assembler::notZero, flush_line);
95+ if (1 <= X86ICacheSync && X86ICacheSync <= 3 ) {
96+ __ bind (flush_line);
97+ x86_generate_icache_flush_insn (_masm, addr);
98+ __ addptr (addr, ICache::line_size);
99+ __ decrementl (lines);
100+ __ jccb (Assembler::notZero, flush_line);
54101
55- __ mfence ();
102+ x86_generate_icache_fence (_masm);
103+ }
56104
57105 __ bind (done);
58106
59- #else
60- const Address magic (rsp, 3 *wordSize);
61- __ lock (); __ addl (Address (rsp, 0 ), 0 );
62- #endif // AMD64
63107 __ movptr (rax, magic); // Handshake with caller to make sure it happened!
64108 __ ret (0 );
65109
66110 // Must be set here so StubCodeMark destructor can call the flush stub.
67111 *flush_icache_stub = (ICache::flush_icache_stub_t )start;
68112}
69113
114+ void ICache::initialize (int phase) {
115+ switch (phase) {
116+ case 1 : {
117+ // Initial phase, we assume only CLFLUSH is available.
118+ IntFlagSetting fs (X86ICacheSync, 1 );
119+ AbstractICache::initialize (phase);
120+ break ;
121+ }
122+ case 2 : {
123+ // Final phase, generate the stub again.
124+ AbstractICache::initialize (phase);
125+ break ;
126+ }
127+ default :
128+ ShouldNotReachHere ();
129+ }
130+ }
131+
70132#undef __
0 commit comments