0939fd2c61a3f45b5af02503d4708174304def41
[cacao.git] / src / vm / jit / sparc64 / patcher.c
1 /* src/vm/jit/mips/patcher.c - MIPS code patching functions
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Christian Thalinger
28
29    Changes:
30
31    $Id: patcher.c 5164 2006-07-19 15:54:01Z twisti $
32
33 */
34
35
36 #include "config.h"
37
38 #include <assert.h>
39
40 #include "vm/types.h"
41
42 #include "vm/jit/sparc64/codegen.h"
43
44 #include "mm/memory.h"
45 #include "native/native.h"
46 #include "vm/builtin.h"
47 #include "vm/class.h"
48 #include "vm/exceptions.h"
49 #include "vm/field.h"
50 #include "vm/initialize.h"
51 #include "vm/options.h"
52 #include "vm/resolve.h"
53 #include "vm/references.h"
54 #include "vm/jit/asmpart.h"
55 #include "vm/jit/patcher.h"
56
57 #include "vm/jit/sparc64/md-abi.h"
58
59
60 /* patcher_wrapper *************************************************************
61
62    Wrapper for all patchers.  It also creates the stackframe info
63    structure.
64
65    If the return value of the patcher function is false, it gets the
66    exception object, clears the exception pointer and returns the
67    exception.
68
69 *******************************************************************************/
70
71 java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
72 {
73         stackframeinfo     sfi;
74         u1                *xpc;
75         u1                *javasp;
76         java_objectheader *o;
77 #if SIZEOF_VOID_P == 8
78         u8                mcode;
79 #else
80         u4                mcode[2];
81 #endif
82         functionptr        f;
83         bool               result;
84         java_objectheader *e;
85         
86
87         /* define the patcher function */
88
89         bool (*patcher_function)(u1 *);
90
91         assert(pv != NULL);
92
93         /* get stuff from the stack */
94
95         xpc = (u1 *)                *((ptrint *) (sp + 5 * 8));
96         o   = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
97         f   = (functionptr)         *((ptrint *) (sp + 0 * 8));
98
99         /* store PV into the patcher function position */
100
101         *((ptrint *) (sp + 0 * 8)) = (ptrint) pv;
102
103         /* cast the passed function to a patcher function */
104
105         patcher_function = (bool (*)(u1 *)) (ptrint) f;
106
107         /* enter a monitor on the patching position */
108
109         PATCHER_MONITORENTER;
110         
111         /* calculate sp of the current java function considering the WINSAVE regs */
112         
113         javasp = sp - 16 * 8 - BIAS;
114
115         /* create the stackframeinfo */
116
117         stacktrace_create_extern_stackframeinfo(&sfi, pv, javasp, ra, xpc);
118
119         /* call the proper patcher function */
120
121         result = (patcher_function)(sp);
122
123         /* remove the stackframeinfo */
124
125         stacktrace_remove_stackframeinfo(&sfi);
126
127         /* check for return value and exit accordingly */
128
129         if (result == false) {
130                 e = exceptions_get_and_clear_exception();
131
132                 PATCHER_MONITOREXIT;
133
134                 return e;
135         }
136
137         /* patch back original code */
138
139 #if SIZEOF_VOID_P == 8
140         mcode    =                      *((u8 *)     (sp + 3 * 8));
141
142         *((u4 *) (xpc + 0 * 4)) = mcode;
143         *((u4 *) (xpc + 1 * 4)) = mcode >> 32;
144 #else
145         mcode[0] =                      *((u4 *)     (sp + 3 * 8));
146         mcode[1] =                      *((u4 *)     (sp + 3 * 8 + 4));
147
148         *((u4 *) (xpc + 0 * 4)) = mcode[0];
149         *((u4 *) (xpc + 1 * 4)) = mcode[1];
150 #endif
151
152
153         /* synchronize instruction cache */
154
155         md_icacheflush(xpc, PATCHER_CALL_SIZE);
156
157         PATCHER_MARK_PATCHED_MONITOREXIT;
158
159         return NULL;
160 }
161
162
163 /* patcher_get_putstatic *******************************************************
164
165    Machine code:
166
167    <patched call position>
168    xxx         ldx      at,-72(pv)
169    xxx         ld       a1,0(at)
170
171 *******************************************************************************/
172
173 bool patcher_get_putstatic(u1 *sp)
174 {
175         unresolved_field *uf;
176         s4                disp;
177         u1               *pv;
178         fieldinfo        *fi;
179
180         /* get stuff from the stack */
181
182
183         uf       = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
184         disp     =                      *((s4 *)     (sp + 1 * 8));
185         pv       = (u1 *)               *((ptrint *) (sp + 0 * 8));
186
187         /* get the fieldinfo */
188
189         if (!(fi = resolve_field_eager(uf)))
190                 return false;
191
192         /* check if the field's class is initialized */
193
194         if (!(fi->class->state & CLASS_INITIALIZED))
195                 if (!initialize_class(fi->class))
196                         return false;
197
198         /* patch the field value's address */
199
200         *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
201
202         /* synchronize data cache */
203
204         md_dcacheflush(pv + disp, SIZEOF_VOID_P);
205
206         return true;
207 }
208
209
210 /* patcher_get_putfield ********************************************************
211
212    Machine code:
213
214    <patched call position>
215    8ee90020    lw       a5,32(s7)
216
217 *******************************************************************************/
218
219 bool patcher_get_putfield(u1 *sp)
220 {
221         u1               *ra;
222 #if SIZEOF_VOID_P == 8
223         u8                mcode;
224 #else
225         u4                mcode[2];
226 #endif
227         unresolved_field *uf;
228         fieldinfo        *fi;
229
230         assert(0);
231
232         ra       = (u1 *)               *((ptrint *) (sp + 5 * 8));
233 #if SIZEOF_VOID_P == 8
234         mcode    =                      *((u8 *)     (sp + 3 * 8));
235 #else
236         mcode[0] =                      *((u4 *)     (sp + 3 * 8));
237         mcode[1] =                      *((u4 *)     (sp + 3 * 8 + 4));
238 #endif
239         uf       = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
240
241         /* get the fieldinfo */
242
243         if (!(fi = resolve_field_eager(uf)))
244                 return false;
245
246         /* patch back original code */
247
248 #if SIZEOF_VOID_P == 8
249         *((u4 *) (ra + 0 * 4)) = mcode;
250         *((u4 *) (ra + 1 * 4)) = mcode >> 32;
251 #else
252         *((u4 *) (ra + 0 * 4)) = mcode[0];
253         *((u4 *) (ra + 1 * 4)) = mcode[1];
254 #endif
255
256         /* if we show disassembly, we have to skip the nop's */
257
258         if (opt_shownops) {
259                 ra = ra + PATCHER_CALL_SIZE;
260
261 #if SIZEOF_VOID_P == 4
262         if (fi->type == TYPE_LNG) {
263 # if WORDS_BIGENDIAN == 1
264                 /* ATTENTION: order of these instructions depend on M_LLD_INTERN */
265                 *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff);
266                 *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff);
267 # else
268                 /* ATTENTION: order of these instructions depend on M_LLD_INTERN */
269                 *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff);
270                 *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff);
271 # endif
272         } else
273 #endif
274                 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
275
276         /* synchronize instruction cache */
277
278         if (opt_showdisassemble) {
279 #if SIZEOF_VOID_P == 4
280                 if (fi->type == TYPE_LNG)
281                         md_icacheflush(ra - 2 * 4, 4 * 4);
282                 else
283 #endif
284                         md_icacheflush(ra - 2 * 4, 3 * 4);
285         }
286         else {
287                 md_icacheflush(ra, 2 * 4);
288         }
289 }
290
291         return true;
292 }
293
294
295 /* patcher_aconst **************************************************************
296
297    Machine code:
298
299    <patched call postition>
300    xxx         ld       a0,-104(pv)
301
302 *******************************************************************************/
303
304 bool patcher_aconst(u1 *sp)
305 {
306         constant_classref *cr;
307         s4                 disp;
308         u1                *pv;
309         classinfo         *c;
310
311         /* get stuff from the stack */
312
313         cr       = (constant_classref *) *((ptrint *) (sp + 2 * 8));
314         disp     =                       *((s4 *)     (sp + 1 * 8));
315         pv       = (u1 *)                *((ptrint *) (sp + 0 * 8));
316
317         /* get the classinfo */
318
319         if (!(c = resolve_classref_eager(cr)))
320                 return false;
321
322         /* patch the classinfo pointer */
323
324         *((ptrint *) (pv + disp)) = (ptrint) c;
325
326         /* synchronize data cache */
327
328         md_dcacheflush(pv + disp, SIZEOF_VOID_P);
329
330         return true;
331 }
332
333
334 /* patcher_builtin_multianewarray **********************************************
335
336    Machine code:
337
338    <patched call position>
339    dfc5ff90    ld       a1,-112(s8)
340    03a03025    move     a2,sp
341    dfd9ff88    ld       t9,-120(s8)
342    0320f809    jalr     t9
343    00000000    nop
344
345 *******************************************************************************/
346
347 bool patcher_builtin_multianewarray(u1 *sp)
348 {
349         constant_classref *cr;
350         s4                 disp;
351         u1                *pv;
352         classinfo         *c;
353
354         /* get stuff from the stack */
355
356         cr       = (constant_classref *) *((ptrint *) (sp + 2 * 8));
357         disp     =                       *((s4 *)     (sp + 1 * 8));
358         pv       = (u1 *)                *((ptrint *) (sp + 0 * 8));
359
360         /* get the classinfo */
361
362         if (!(c = resolve_classref_eager(cr)))
363                 return false;
364
365         /* patch the classinfo pointer */
366
367         *((ptrint *) (pv + disp)) = (ptrint) c;
368
369         /* synchronize data cache */
370
371         md_dcacheflush(pv + disp, SIZEOF_VOID_P);
372
373         return true;
374 }
375
376
377 /* patcher_builtin_arraycheckcast **********************************************
378
379    Machine code:
380
381    <patched call position>
382    dfc5ffc0    ld       a1,-64(s8)
383    dfd9ffb8    ld       t9,-72(s8)
384    0320f809    jalr     t9
385    00000000    nop
386
387 *******************************************************************************/
388
389 bool patcher_builtin_arraycheckcast(u1 *sp)
390 {
391         constant_classref *cr;
392         s4                 disp;
393         u1                *pv;
394         classinfo         *c;
395
396         /* get stuff from the stack */
397
398         cr       = (constant_classref *) *((ptrint *) (sp + 2 * 8));
399         disp     =                       *((s4 *)     (sp + 1 * 8));
400         pv       = (u1 *)                *((ptrint *) (sp + 0 * 8));
401
402         /* get the classinfo */
403
404         if (!(c = resolve_classref_eager(cr)))
405                 return false;
406
407         /* patch the classinfo pointer */
408
409         *((ptrint *) (pv + disp)) = (ptrint) c;
410
411         /* synchronize data cache */
412
413         md_dcacheflush(pv + disp, SIZEOF_VOID_P);
414
415         return true;
416 }
417
418
419 /* patcher_invokestatic_special ************************************************
420
421    Machine code:
422
423    <patched call position>
424    dfdeffc0    ld       s8,-64(s8)
425    03c0f809    jalr     s8
426    00000000    nop
427
428 ******************************************************************************/
429
430 bool patcher_invokestatic_special(u1 *sp)
431 {
432         unresolved_method *um;
433         s4                 disp;
434         u1                *pv;
435         methodinfo        *m;
436
437         /* get stuff from the stack */
438
439         um       = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
440         disp     =                       *((s4 *)     (sp + 1 * 8));
441         pv       = (u1 *)                *((ptrint *) (sp + 0 * 8));
442
443         /* get the fieldinfo */
444
445         if (!(m = resolve_method_eager(um)))
446                 return false;
447
448         /* patch stubroutine */
449
450         *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
451
452         /* synchronize data cache */
453
454         md_dcacheflush(pv + disp, SIZEOF_VOID_P);
455
456         return true;
457 }
458
459
460 /* patcher_invokevirtual *******************************************************
461
462    Machine code:
463
464    <patched call position>
465    xxx         ldx      t9,0(a0)
466    xxx         ldx      s8,64(t9)
467    xxx         jmpl     s8
468    00000000    nop
469
470 *******************************************************************************/
471
472 bool patcher_invokevirtual(u1 *sp)
473 {
474         u1                *ra;
475         unresolved_method *um;
476         methodinfo        *m;
477
478         assert(0);
479
480         /* get stuff from the stack */
481
482         ra       = (u1 *)                *((ptrint *) (sp + 5 * 8));
483         um       = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
484
485         /* get the fieldinfo */
486
487         if (!(m = resolve_method_eager(um)))
488                 return false;
489
490         /* if we show disassembly, we have to skip the nop's */
491
492         if (opt_shownops) {
493                 ra = ra + PATCHER_CALL_SIZE;
494
495         /* patch vftbl index */
496
497                 *((s4 *) (ra + 1 * 4)) |=
498                         (s4) ((OFFSET(vftbl_t, table[0]) +
499                                    sizeof(methodptr) * m->vftblindex) & 0x00001fff);
500
501         /* synchronize instruction cache */
502
503                 md_icacheflush(ra + 1 * 4, 1 * 4);
504         }
505         else {
506                 /* patch vftbl index */
507
508                 *((s4 *) (sp + 3 * 8 + 4)) |=
509                         (s4) ((OFFSET(vftbl_t, table[0]) +
510                                    sizeof(methodptr) * m->vftblindex) & 0x00001fff);
511         }
512
513         return true;
514 }
515
516
517 /* patcher_invokeinterface *****************************************************
518
519    Machine code:
520
521    <patched call position>
522    dc990000    ld       t9,0(a0)
523    df39ffa0    ld       t9,-96(t9)
524    df3e0018    ld       s8,24(t9)
525    03c0f809    jalr     s8
526    00000000    nop
527
528 *******************************************************************************/
529
530 bool patcher_invokeinterface(u1 *sp)
531 {
532         u1                *ra;
533 #if SIZEOF_VOID_P == 8
534         u8                 mcode;
535 #else
536         u4                 mcode[2];
537 #endif
538         unresolved_method *um;
539         methodinfo        *m;
540
541         assert(0);
542
543         /* get stuff from the stack */
544
545         ra       = (u1 *)                *((ptrint *) (sp + 5 * 8));
546 #if SIZEOF_VOID_P == 8
547         mcode    =                       *((u8 *)     (sp + 3 * 8));
548 #else
549         mcode[0] =                       *((u4 *)     (sp + 3 * 8));
550         mcode[1] =                       *((u4 *)     (sp + 3 * 8 + 4));
551 #endif
552         um       = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
553
554         /* get the fieldinfo */
555
556         if (!(m = resolve_method_eager(um)))
557                 return false;
558
559         /* patch back original code */
560
561 #if SIZEOF_VOID_P == 8
562         *((u4 *) (ra + 0 * 4)) = mcode;
563         *((u4 *) (ra + 1 * 4)) = mcode >> 32;
564 #else
565         *((u4 *) (ra + 0 * 4)) = mcode[0];
566         *((u4 *) (ra + 1 * 4)) = mcode[1];
567 #endif
568
569         /* if we show disassembly, we have to skip the nop's */
570
571         if (opt_showdisassemble)
572                 ra = ra + 2 * 4;
573
574         /* patch interfacetable index */
575
576         *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
577                                                                          sizeof(methodptr*) * m->class->index) & 0x0000ffff);
578
579         /* patch method offset */
580
581         *((s4 *) (ra + 2 * 4)) |=
582                 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
583
584         /* synchronize instruction cache */
585
586         if (opt_showdisassemble)
587                 md_icacheflush(ra - 2 * 4, 5 * 4);
588         else
589                 md_icacheflush(ra, 3 * 4);
590
591         return true;
592 }
593
594
595 /* patcher_checkcast_instanceof_flags ******************************************
596
597    Machine code:
598
599    <patched call position>
600    8fc3ff24    lw       v1,-220(s8)
601    30630200    andi     v1,v1,512
602    1060000d    beq      v1,zero,0x000000001051824c
603    00000000    nop
604
605 *******************************************************************************/
606
607 bool patcher_checkcast_instanceof_flags(u1 *sp)
608 {
609         constant_classref *cr;
610         s4                 disp;
611         u1                *pv;
612         classinfo         *c;
613
614         /* get stuff from the stack */
615
616         cr       = (constant_classref *) *((ptrint *) (sp + 2 * 8));
617         disp     =                       *((s4 *)     (sp + 1 * 8));
618         pv       = (u1 *)                *((ptrint *) (sp + 0 * 8));
619
620         /* get the fieldinfo */
621
622         if (!(c = resolve_classref_eager(cr)))
623                 return false;
624
625         /* patch class flags */
626
627         *((s4 *) (pv + disp)) = (s4) c->flags;
628
629         /* synchronize data cache */
630
631         md_dcacheflush(pv + disp, sizeof(s4));
632
633         return true;
634 }
635
636
637 /* patcher_checkcast_instanceof_interface **************************************
638
639    Machine code:
640
641    <patched call position>
642    dd030000    ld       v1,0(a4)
643    8c79001c    lw       t9,28(v1)
644    27390000    addiu    t9,t9,0
645    1b200082    blez     t9,zero,0x000000001051843c
646    00000000    nop
647    dc790000    ld       t9,0(v1)
648
649 *******************************************************************************/
650
651 bool patcher_checkcast_instanceof_interface(u1 *sp)
652 {
653         u1                *ra;
654 #if SIZEOF_VOID_P == 8
655         u8                 mcode;
656 #else
657         u4                 mcode[2];
658 #endif
659         constant_classref *cr;
660         classinfo         *c;
661
662         assert(0);
663
664         /* get stuff from the stack */
665
666         ra       = (u1 *)                *((ptrint *) (sp + 5 * 8));
667 #if SIZEOF_VOID_P == 8
668         mcode    =                       *((u8 *)     (sp + 3 * 8));
669 #else
670         mcode[0] =                       *((u4 *)     (sp + 3 * 8));
671         mcode[1] =                       *((u4 *)     (sp + 3 * 8 + 4));
672 #endif
673         cr       = (constant_classref *) *((ptrint *) (sp + 2 * 8));
674
675         /* get the fieldinfo */
676
677         if (!(c = resolve_classref_eager(cr)))
678                 return false;
679
680         /* patch back original code */
681
682 #if SIZEOF_VOID_P == 8
683         *((u4 *) (ra + 0 * 4)) = mcode;
684         *((u4 *) (ra + 1 * 4)) = mcode >> 32;
685 #else
686         *((u4 *) (ra + 0 * 4)) = mcode[0];
687         *((u4 *) (ra + 1 * 4)) = mcode[1];
688 #endif
689
690         /* if we show disassembly, we have to skip the nop's */
691
692         if (opt_showdisassemble)
693                 ra = ra + 2 * 4;
694
695         /* patch super class index */
696
697         *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
698
699         *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
700                                                                          c->index * sizeof(methodptr*)) & 0x0000ffff);
701
702         /* synchronize instruction cache */
703
704         if (opt_showdisassemble)
705                 md_icacheflush(ra - 2 * 4, 8 * 4);
706         else
707                 md_icacheflush(ra, 6 * 4);
708
709         return true;
710 }
711
712
713 /* patcher_checkcast_instanceof_class ******************************************
714
715    Machine code:
716
717    <patched call position>
718    dd030000    ld       v1,0(a4)
719    dfd9ff18    ld       t9,-232(s8)
720
721 *******************************************************************************/
722
723 bool patcher_checkcast_instanceof_class(u1 *sp)
724 {
725         constant_classref *cr;
726         s4                 disp;
727         u1                *pv;
728         classinfo         *c;
729
730         /* get stuff from the stack */
731
732         cr       = (constant_classref *) *((ptrint *) (sp + 2 * 8));
733         disp     =                       *((s4 *)     (sp + 1 * 8));
734         pv       = (u1 *)                *((ptrint *) (sp + 0 * 8));
735
736         /* get the fieldinfo */
737
738         if (!(c = resolve_classref_eager(cr)))
739                 return false;
740
741         /* patch super class' vftbl */
742
743         *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
744
745         /* synchronize data cache */
746
747         md_dcacheflush(pv + disp, SIZEOF_VOID_P);
748
749         return true;
750 }
751
752
753 /* patcher_clinit **************************************************************
754
755    No special machine code.
756
757 *******************************************************************************/
758
759 bool patcher_clinit(u1 *sp)
760 {
761         classinfo *c;
762
763         /* get stuff from the stack */
764
765         c        = (classinfo *) *((ptrint *) (sp + 2 * 8));
766
767         /* check if the class is initialized */
768
769         if (!(c->state & CLASS_INITIALIZED))
770                 if (!initialize_class(c))
771                         return false;
772
773         return true;
774 }
775
776
777 /* patcher_athrow_areturn ******************************************************
778
779    Machine code:
780
781    <patched call position>
782
783 *******************************************************************************/
784
785 #ifdef ENABLE_VERIFIER
786 bool patcher_athrow_areturn(u1 *sp)
787 {
788         unresolved_class *uc;
789         classinfo        *c;
790
791         /* get stuff from the stack */
792
793         uc       = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
794
795         /* resolve the class */
796
797         if (!resolve_class(uc, resolveEager, false, &c))
798                 return false;
799
800         return true;
801 }
802 #endif /* ENABLE_VERIFIER */
803
804
805 /* patcher_resolve_native ******************************************************
806
807    XXX
808
809 *******************************************************************************/
810
811 #if !defined(WITH_STATIC_CLASSPATH)
812 bool patcher_resolve_native(u1 *sp)
813 {
814         methodinfo  *m;
815         s4           disp;
816         u1          *pv;
817         functionptr  f;
818
819         /* get stuff from the stack */
820
821         m        = (methodinfo *) *((ptrint *) (sp + 2 * 8));
822         disp     =                *((s4 *)     (sp + 1 * 8));
823         pv       = (u1 *)         *((ptrint *) (sp + 0 * 8));
824
825         /* return address on SPARC is address of jump, therefore correct */
826
827         /* resolve native function */
828
829         if (!(f = native_resolve_function(m)))
830                 return false;
831
832         /* patch native function pointer */
833
834         *((ptrint *) (pv + disp)) = (ptrint) f;
835
836         /* synchronize data cache */
837
838         md_dcacheflush(pv + disp, SIZEOF_VOID_P);
839
840         return true;
841 }
842 #endif /* !defined(WITH_STATIC_CLASSPATH) */
843
844
845 /*
846  * These are local overrides for various environment variables in Emacs.
847  * Please do not remove this and leave it at the end of the file, where
848  * Emacs will automagically detect them.
849  * ---------------------------------------------------------------------
850  * Local variables:
851  * mode: c
852  * indent-tabs-mode: t
853  * c-basic-offset: 4
854  * tab-width: 4
855  * End:
856  * vim:noexpandtab:sw=4:ts=4:
857  */