aoqi@0: /* aoqi@0: * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: * aoqi@0: */ aoqi@0: aoqi@0: #include "precompiled.hpp" aoqi@0: #include "runtime/sharedRuntime.hpp" aoqi@0: #include "utilities/copy.hpp" aoqi@0: aoqi@0: aoqi@0: // Copy bytes; larger units are filled atomically if everything is aligned. aoqi@0: void Copy::conjoint_memory_atomic(void* from, void* to, size_t size) { aoqi@0: address src = (address) from; aoqi@0: address dst = (address) to; aoqi@0: uintptr_t bits = (uintptr_t) src | (uintptr_t) dst | (uintptr_t) size; aoqi@0: aoqi@0: // (Note: We could improve performance by ignoring the low bits of size, aoqi@0: // and putting a short cleanup loop after each bulk copy loop. aoqi@0: // There are plenty of other ways to make this faster also, aoqi@0: // and it's a slippery slope. For now, let's keep this code simple aoqi@0: // since the simplicity helps clarify the atomicity semantics of aoqi@0: // this operation. There are also CPU-specific assembly versions aoqi@0: // which may or may not want to include such optimizations.) aoqi@0: aoqi@0: if (bits % sizeof(jlong) == 0) { aoqi@0: Copy::conjoint_jlongs_atomic((jlong*) src, (jlong*) dst, size / sizeof(jlong)); aoqi@0: } else if (bits % sizeof(jint) == 0) { aoqi@0: Copy::conjoint_jints_atomic((jint*) src, (jint*) dst, size / sizeof(jint)); aoqi@0: } else if (bits % sizeof(jshort) == 0) { aoqi@0: Copy::conjoint_jshorts_atomic((jshort*) src, (jshort*) dst, size / sizeof(jshort)); aoqi@0: } else { aoqi@0: // Not aligned, so no need to be atomic. aoqi@0: Copy::conjoint_jbytes((void*) src, (void*) dst, size); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: // Fill bytes; larger units are filled atomically if everything is aligned. aoqi@0: void Copy::fill_to_memory_atomic(void* to, size_t size, jubyte value) { aoqi@0: address dst = (address) to; aoqi@0: uintptr_t bits = (uintptr_t) to | (uintptr_t) size; aoqi@0: if (bits % sizeof(jlong) == 0) { aoqi@0: jlong fill = (julong)( (jubyte)value ); // zero-extend aoqi@0: if (fill != 0) { aoqi@0: fill += fill << 8; aoqi@0: fill += fill << 16; aoqi@0: fill += fill << 32; aoqi@0: } aoqi@0: //Copy::fill_to_jlongs_atomic((jlong*) dst, size / sizeof(jlong)); aoqi@0: for (uintptr_t off = 0; off < size; off += sizeof(jlong)) { aoqi@0: *(jlong*)(dst + off) = fill; aoqi@0: } aoqi@0: } else if (bits % sizeof(jint) == 0) { aoqi@0: jint fill = (juint)( (jubyte)value ); // zero-extend aoqi@0: if (fill != 0) { aoqi@0: fill += fill << 8; aoqi@0: fill += fill << 16; aoqi@0: } aoqi@0: //Copy::fill_to_jints_atomic((jint*) dst, size / sizeof(jint)); aoqi@0: for (uintptr_t off = 0; off < size; off += sizeof(jint)) { aoqi@0: *(jint*)(dst + off) = fill; aoqi@0: } aoqi@0: } else if (bits % sizeof(jshort) == 0) { aoqi@0: jshort fill = (jushort)( (jubyte)value ); // zero-extend aoqi@0: fill += fill << 8; aoqi@0: //Copy::fill_to_jshorts_atomic((jshort*) dst, size / sizeof(jshort)); aoqi@0: for (uintptr_t off = 0; off < size; off += sizeof(jshort)) { aoqi@0: *(jshort*)(dst + off) = fill; aoqi@0: } aoqi@0: } else { aoqi@0: // Not aligned, so no need to be atomic. aoqi@0: Copy::fill_to_bytes(dst, size, value); aoqi@0: } aoqi@0: }