/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/codeBuffer.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
// Implementation of StubRoutines - for a description
// of how to extend it, see the header file.
// Class Variables
// Compiled code entry points default values
// The default functions don't have separate disjoint versions.
address StubRoutines::_oop_arraycopy_uninit = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy_uninit);
address StubRoutines::_jbyte_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jbyte_copy);
address StubRoutines::_jshort_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jshort_copy);
address StubRoutines::_jint_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jint_copy);
address StubRoutines::_jlong_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::jlong_copy);
address StubRoutines::_oop_disjoint_arraycopy_uninit = CAST_FROM_FN_PTR(address, StubRoutines::oop_copy_uninit);
address StubRoutines::_arrayof_jbyte_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jbyte_copy);
address StubRoutines::_arrayof_jshort_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jshort_copy);
address StubRoutines::_arrayof_jint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jint_copy);
address StubRoutines::_arrayof_jlong_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jlong_copy);
address StubRoutines::_arrayof_oop_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy);
address StubRoutines::_arrayof_oop_arraycopy_uninit = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy_uninit);
address StubRoutines::_arrayof_jbyte_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jbyte_copy);
address StubRoutines::_arrayof_jshort_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jshort_copy);
address StubRoutines::_arrayof_jint_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jint_copy);
address StubRoutines::_arrayof_jlong_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_jlong_copy);
address StubRoutines::_arrayof_oop_disjoint_arraycopy = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy);
address StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy_uninit);
// Initialization
//
// Note: to break cycle with universe initialization, stubs are generated in two phases.
// The first one generates stubs needed during universe init (e.g., _handle_must_compile_first_entry).
// The second phase includes all other stubs (which may depend on universe being initialized.)
}
StubGenerator_generate(&buffer, false);
}
}
#ifdef ASSERT
// simple tests of generated arraycopy functions
int v = 0xcc;
unsigned int i;
for (i = 0; i < sizeof(lbuffer); i++) {
}
// C++ does not guarantee jlong[] array alignment to 8 bytes.
// Use middle of array to check that memory before it is not modified.
// do an aligned copy
for (i = 0; i < sizeof(lbuffer); i++) {
}
// adjust destination alignment
for (i = 0; i < sizeof(lbuffer); i++) {
}
// adjust source alignment
for (i = 0; i < sizeof(lbuffer); i++) {
}
}
#endif
}
StubGenerator_generate(&buffer, true);
}
#ifdef ASSERT
// Make sure all the arraycopy stubs properly handle zero count
union { \
double d; \
} s; \
\
int v = 32; \
for (int i = 0; i < 96; i++) { \
s.body[i] = 1; \
} \
if (aligned) { \
} else { \
continue; \
} \
} else { \
} \
for (int i = 0; i < 96; i++) { \
} else { \
} \
} \
} \
} \
} \
test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::arrayof_conjoint_##type##s), (int)MAX2(sizeof(HeapWord), sizeof(type)))
// Make sure all the copy runtime routines properly handle zero count
// Aligned to BytesPerLong
#endif
}
//
// Default versions of arraycopy functions
//
}
}
#ifndef PRODUCT
#endif // !PRODUCT
#ifndef PRODUCT
#endif // !PRODUCT
#ifndef PRODUCT
#endif // !PRODUCT
#ifndef PRODUCT
#endif // !PRODUCT
#ifndef PRODUCT
#endif // !PRODUCT
#ifndef PRODUCT
#endif // !PRODUCT
#ifndef PRODUCT
#endif // !PRODUCT
#ifndef PRODUCT
#endif // !PRODUCT
#ifndef PRODUCT
#endif // !PRODUCT
#ifndef PRODUCT
#endif // !PRODUCT
#ifndef PRODUCT
#endif // !PRODUCT
#ifndef PRODUCT
#endif // !PRODUCT
return StubRoutines::xxx_fill(); }
switch (t) {
case T_BYTE:
case T_BOOLEAN:
case T_CHAR:
case T_SHORT:
case T_INT:
case T_FLOAT:
case T_DOUBLE:
case T_LONG:
case T_ARRAY:
case T_OBJECT:
case T_NARROWOOP:
case T_ADDRESS:
// Currently unsupported
return NULL;
default:
return NULL;
}
}
// constants for computing the copy function
enum {
COPYFUNC_UNALIGNED = 0,
COPYFUNC_CONJOINT = 0,
};
// Note: The condition "disjoint" applies also for overlapping copies
// where an descending copy is permitted (i.e., dest_offset <= src_offset).
StubRoutines::select_arraycopy_function(BasicType t, bool aligned, bool disjoint, const char* &name, bool dest_uninitialized) {
int selector =
name = #xxx_arraycopy; \
return StubRoutines::xxx_arraycopy(); }
name = #xxx_arraycopy; \
switch (t) {
case T_BYTE:
case T_BOOLEAN:
switch (selector) {
}
case T_CHAR:
case T_SHORT:
switch (selector) {
}
case T_INT:
case T_FLOAT:
switch (selector) {
}
case T_DOUBLE:
case T_LONG:
switch (selector) {
}
case T_ARRAY:
case T_OBJECT:
switch (selector) {
case COPYFUNC_CONJOINT | COPYFUNC_ALIGNED: RETURN_STUB_PARM(arrayof_oop_arraycopy, dest_uninitialized);
case COPYFUNC_DISJOINT | COPYFUNC_UNALIGNED: RETURN_STUB_PARM(oop_disjoint_arraycopy, dest_uninitialized);
case COPYFUNC_DISJOINT | COPYFUNC_ALIGNED: RETURN_STUB_PARM(arrayof_oop_disjoint_arraycopy, dest_uninitialized);
}
default:
return NULL;
}
}