copy_sparc.hpp revision 113:ba764ed4b6f2
1236769Sobrien/*
2236769Sobrien * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
3236769Sobrien * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4236769Sobrien *
5236769Sobrien * This code is free software; you can redistribute it and/or modify it
6236769Sobrien * under the terms of the GNU General Public License version 2 only, as
7236769Sobrien * published by the Free Software Foundation.
8236769Sobrien *
9236769Sobrien * This code is distributed in the hope that it will be useful, but WITHOUT
10236769Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11236769Sobrien * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12236769Sobrien * version 2 for more details (a copy is included in the LICENSE file that
13236769Sobrien * accompanied this code).
14236769Sobrien *
15236769Sobrien * You should have received a copy of the GNU General Public License version
16236769Sobrien * 2 along with this work; if not, write to the Free Software Foundation,
17236769Sobrien * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18236769Sobrien *
19236769Sobrien * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20236769Sobrien * CA 95054 USA or visit www.sun.com if you need additional information or
21236769Sobrien * have any questions.
22236769Sobrien *
23236769Sobrien */
24236769Sobrien
25236769Sobrien// Inline functions for memory copy and fill.
26236769Sobrien
27236769Sobrienstatic void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
28236769Sobrien  (void)memmove(to, from, count * HeapWordSize);
29236769Sobrien}
30236769Sobrien
31236769Sobrienstatic void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
32236769Sobrien  switch (count) {
33236769Sobrien  case 8:  to[7] = from[7];
34236769Sobrien  case 7:  to[6] = from[6];
35236769Sobrien  case 6:  to[5] = from[5];
36236769Sobrien  case 5:  to[4] = from[4];
37236769Sobrien  case 4:  to[3] = from[3];
38236769Sobrien  case 3:  to[2] = from[2];
39236769Sobrien  case 2:  to[1] = from[1];
40236769Sobrien  case 1:  to[0] = from[0];
41236769Sobrien  case 0:  break;
42236769Sobrien  default: (void)memcpy(to, from, count * HeapWordSize);
43236769Sobrien           break;
44236769Sobrien  }
45236769Sobrien}
46236769Sobrien
47236769Sobrienstatic void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
48236769Sobrien  switch (count) {
49236769Sobrien  case 8:  to[7] = from[7];
50236769Sobrien  case 7:  to[6] = from[6];
51236769Sobrien  case 6:  to[5] = from[5];
52236769Sobrien  case 5:  to[4] = from[4];
53236769Sobrien  case 4:  to[3] = from[3];
54236769Sobrien  case 3:  to[2] = from[2];
55236769Sobrien  case 2:  to[1] = from[1];
56236769Sobrien  case 1:  to[0] = from[0];
57236769Sobrien  case 0:  break;
58236769Sobrien  default: while (count-- > 0) {
59236769Sobrien             *to++ = *from++;
60236769Sobrien           }
61236769Sobrien           break;
62236769Sobrien  }
63236769Sobrien}
64236769Sobrien
65236769Sobrienstatic void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
66236769Sobrien  (void)memmove(to, from, count * HeapWordSize);
67236769Sobrien}
68236769Sobrien
69236769Sobrienstatic void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
70236769Sobrien  pd_disjoint_words(from, to, count);
71236769Sobrien}
72236769Sobrien
73236769Sobrienstatic void pd_conjoint_bytes(void* from, void* to, size_t count) {
74236769Sobrien  (void)memmove(to, from, count);
75236769Sobrien}
76236769Sobrien
77236769Sobrienstatic void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
78236769Sobrien  (void)memmove(to, from, count);
79236769Sobrien}
80236769Sobrien
81236769Sobrienstatic void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
82236769Sobrien  // FIXME
83236769Sobrien  (void)memmove(to, from, count << LogBytesPerShort);
84236769Sobrien}
85236769Sobrien
86236769Sobrienstatic void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
87236769Sobrien  // FIXME
88236769Sobrien  (void)memmove(to, from, count << LogBytesPerInt);
89236769Sobrien}
90236769Sobrien
91236769Sobrienstatic void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
92236769Sobrien#ifdef _LP64
93236769Sobrien  assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
94236769Sobrien  pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
95236769Sobrien#else
96236769Sobrien  // Guarantee use of ldd/std via some asm code, because compiler won't.
97236769Sobrien  // See solaris_sparc.il.
98236769Sobrien  _Copy_conjoint_jlongs_atomic(from, to, count);
99236769Sobrien#endif
100236769Sobrien}
101236769Sobrien
102236769Sobrienstatic void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
103236769Sobrien  // Do better than this: inline memmove body  NEEDS CLEANUP
104236769Sobrien  if (from > to) {
105236769Sobrien    while (count-- > 0) {
106236769Sobrien      // Copy forwards
107236769Sobrien      *to++ = *from++;
108236769Sobrien    }
109236769Sobrien  } else {
110236769Sobrien    from += count - 1;
111236769Sobrien    to   += count - 1;
112236769Sobrien    while (count-- > 0) {
113236769Sobrien      // Copy backwards
114236769Sobrien      *to-- = *from--;
115236769Sobrien    }
116236769Sobrien  }
117236769Sobrien}
118236769Sobrien
119236769Sobrienstatic void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
120236769Sobrien  pd_conjoint_bytes_atomic(from, to, count);
121236769Sobrien}
122236769Sobrien
123236769Sobrienstatic void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
124236769Sobrien  pd_conjoint_jshorts_atomic((jshort*)from, (jshort*)to, count);
125236769Sobrien}
126236769Sobrien
127236769Sobrienstatic void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
128236769Sobrien  pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
129236769Sobrien}
130236769Sobrien
131236769Sobrienstatic void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
132236769Sobrien  pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
133236769Sobrien}
134236769Sobrien
135236769Sobrienstatic void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
136236769Sobrien  pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
137236769Sobrien}
138236769Sobrien
139236769Sobrienstatic void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
140236769Sobrien#ifdef _LP64
141236769Sobrien  guarantee(mask_bits((uintptr_t)tohw, right_n_bits(LogBytesPerLong)) == 0,
142236769Sobrien         "unaligned fill words");
143236769Sobrien  julong* to = (julong*)tohw;
144236769Sobrien  julong  v  = ((julong)value << 32) | value;
145236769Sobrien  while (count-- > 0) {
146236769Sobrien    *to++ = v;
147236769Sobrien  }
148236769Sobrien#else // _LP64
149236769Sobrien  juint* to = (juint*)tohw;
150236769Sobrien  while (count-- > 0) {
151236769Sobrien    *to++ = value;
152236769Sobrien  }
153236769Sobrien#endif // _LP64
154236769Sobrien}
155236769Sobrien
156236769Sobrienstatic void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) {
157236769Sobrien  assert(MinObjAlignmentInBytes == BytesPerLong, "need alternate implementation");
158236769Sobrien
159236769Sobrien   julong* to = (julong*)tohw;
160236769Sobrien   julong  v  = ((julong)value << 32) | value;
161236769Sobrien   // If count is odd, odd will be equal to 1 on 32-bit platform
162236769Sobrien   // and be equal to 0 on 64-bit platform.
163236769Sobrien   size_t odd = count % (BytesPerLong / HeapWordSize) ;
164236769Sobrien
165236769Sobrien   size_t aligned_count = align_object_size(count - odd) / HeapWordsPerLong;
166236769Sobrien   julong* end = ((julong*)tohw) + aligned_count - 1;
167236769Sobrien   while (to <= end) {
168236769Sobrien     DEBUG_ONLY(count -= BytesPerLong / HeapWordSize ;)
169236769Sobrien     *to++ = v;
170236769Sobrien   }
171236769Sobrien   assert(count == odd, "bad bounds on loop filling to aligned words");
172236769Sobrien   if (odd) {
173236769Sobrien     *((juint*)to) = value;
174236769Sobrien
175236769Sobrien   }
176236769Sobrien}
177236769Sobrien
178236769Sobrienstatic void pd_fill_to_bytes(void* to, size_t count, jubyte value) {
179236769Sobrien  (void)memset(to, value, count);
180236769Sobrien}
181236769Sobrien
182236769Sobrienstatic void pd_zero_to_words(HeapWord* tohw, size_t count) {
183236769Sobrien  pd_fill_to_words(tohw, count, 0);
184236769Sobrien}
185236769Sobrien
186236769Sobrienstatic void pd_zero_to_bytes(void* to, size_t count) {
187236769Sobrien  (void)memset(to, 0, count);
188236769Sobrien}
189236769Sobrien