Mercurial > hg > release > icedtea7-forest-2.3 > hotspot
changeset 816:b4a877d10a20
Zero-assembler port of HotSpot.
Contributed-by: Gary Benson <gbenson@redhat.com>
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/ui/tree/OopTreeNodeAdapter.java Thu Jul 02 11:10:50 2009 -0700 +++ b/agent/src/share/classes/sun/jvm/hotspot/ui/tree/OopTreeNodeAdapter.java Thu Jul 23 15:53:43 2009 +0100 @@ -161,6 +161,8 @@ child = new OopTreeNodeAdapter(field.getValue(getObj()), field.getID(), getTreeTableMode()); } catch (AddressException e) { child = new BadOopTreeNodeAdapter(field.getValueAsOopHandle(getObj()), field.getID(), getTreeTableMode()); + } catch (UnknownOopException e) { + child = new BadOopTreeNodeAdapter(field.getValueAsOopHandle(getObj()), field.getID(), getTreeTableMode()); } } ++curField;
--- a/make/Makefile Thu Jul 02 11:10:50 2009 -0700 +++ b/make/Makefile Thu Jul 23 15:53:43 2009 +0100 @@ -94,6 +94,15 @@ all_debug: jvmg jvmg1 jvmgkernel docs export_debug all_optimized: optimized optimized1 optimizedkernel docs export_optimized +# Core (non-compiler) targets made available with this Makefile +CORE_VM_TARGETS=productcore fastdebugcore optimizedcore jvmgcore + +allcore: all_productcore all_fastdebugcore +all_productcore: productcore docs export_product +all_fastdebugcore: fastdebugcore docs export_fastdebug +all_debugcore: jvmgcore docs export_debug +all_optimizedcore: optimizedcore docs export_optimized + # Do everything world: all create_jdk @@ -116,6 +125,10 @@ $(CD) $(GAMMADIR)/make; \ $(MAKE) VM_TARGET=$@ generic_build2 $(ALT_OUT) +$(CORE_VM_TARGETS): + $(CD) $(GAMMADIR)/make; \ + $(MAKE) VM_TARGET=$@ generic_buildcore $(ALT_OUT) + $(KERNEL_VM_TARGETS): $(CD) $(GAMMADIR)/make; \ $(MAKE) VM_TARGET=$@ generic_buildkernel $(ALT_OUT) @@ -162,6 +175,12 @@ $(MAKE_ARGS) $(VM_TARGET) endif +generic_buildcore: + $(MKDIR) -p $(OUTPUTDIR) + $(CD) $(OUTPUTDIR); \ + $(MAKE) -f $(ABS_OS_MAKEFILE) \ + $(MAKE_ARGS) $(VM_TARGET) + generic_buildkernel: $(MKDIR) -p $(OUTPUTDIR) ifeq ($(OSNAME),windows) @@ -208,13 +227,21 @@ XUSAGE=$(HS_SRC_DIR)/share/vm/Xusage.txt DOCS_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_docs C1_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler1 +ifeq ($(CORE_BUILD), true) +C2_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_core +else C2_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2 +endif KERNEL_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_kernel C1_DIR=$(C1_BASE_DIR)/$(VM_SUBDIR) C2_DIR=$(C2_BASE_DIR)/$(VM_SUBDIR) KERNEL_DIR=$(KERNEL_BASE_DIR)/$(VM_SUBDIR) # Misc files and generated files need to come from C1 or C2 area +ifeq ($(CORE_BUILD), true) + MISC_DIR=$(C2_DIR) + GEN_DIR=$(C2_BASE_DIR)/generated +else ifeq ($(ARCH_DATA_MODEL), 32) MISC_DIR=$(C1_DIR) GEN_DIR=$(C1_BASE_DIR)/generated @@ -222,6 +249,7 @@ MISC_DIR=$(C2_DIR) GEN_DIR=$(C2_BASE_DIR)/generated endif +endif # Bin files (windows) ifeq ($(OSNAME),windows)
--- a/make/defs.make Thu Jul 02 11:10:50 2009 -0700 +++ b/make/defs.make Thu Jul 23 15:53:43 2009 +0100 @@ -192,13 +192,14 @@ # Use uname output for SRCARCH, but deal with platform differences. If ARCH # is not explicitly listed below, it is treated as x86. - SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64,$(ARCH))) + SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 zero,$(ARCH))) ARCH/ = x86 ARCH/sparc = sparc ARCH/sparc64= sparc ARCH/ia64 = ia64 ARCH/amd64 = x86 ARCH/x86_64 = x86 + ARCH/zero = zero # BUILDARCH is usually the same as SRCARCH, except for sparcv9 BUILDARCH = $(SRCARCH) @@ -222,8 +223,9 @@ LIBARCH/sparc = sparc LIBARCH/sparcv9 = sparcv9 LIBARCH/ia64 = ia64 + LIBARCH/zero = $(ZERO_LIBARCH) - LP64_ARCH = sparcv9 amd64 ia64 + LP64_ARCH = sparcv9 amd64 ia64 zero endif # Required make macro settings for all platforms
--- a/make/linux/Makefile Thu Jul 02 11:10:50 2009 -0700 +++ b/make/linux/Makefile Thu Jul 23 15:53:43 2009 +0100 @@ -224,11 +224,22 @@ exit 1; \ fi -$(SUBDIRS_TIERED): $(BUILDTREE_MAKE) +# For Zero builds we need to create the platform file from a template. +# For non-Zero builds the file will be read directly from $(GAMMADIR) +ifeq ($(ZERO_BUILD), true) + PLATFORM_FILE = $(OUTPUTDIR)/platform_zero +else + PLATFORM_FILE = +endif + +$(OUTPUTDIR)/platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in + $(SED) 's/@ZERO_ARCHDEF@/$(ZERO_ARCHDEF)/g;s/@ZERO_LIBARCH@/$(ZERO_LIBARCH)/g;' < $< > $@ + +$(SUBDIRS_TIERED): $(BUILDTREE_MAKE) $(PLATFORM_FILE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks $(BUILDTREE) VARIANT=tiered -$(SUBDIRS_C2): $(BUILDTREE_MAKE) +$(SUBDIRS_C2): $(BUILDTREE_MAKE) $(PLATFORM_FILE) ifdef FORCE_TIERED $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks $(BUILDTREE) VARIANT=tiered FORCE_TIERED=1 @@ -237,11 +248,11 @@ $(BUILDTREE) VARIANT=compiler2 endif -$(SUBDIRS_C1): $(BUILDTREE_MAKE) +$(SUBDIRS_C1): $(BUILDTREE_MAKE) $(PLATFORM_FILE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks $(BUILDTREE) VARIANT=compiler1 -$(SUBDIRS_CORE): $(BUILDTREE_MAKE) +$(SUBDIRS_CORE): $(BUILDTREE_MAKE) $(PLATFORM_FILE) $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks $(BUILDTREE) VARIANT=core
--- a/make/linux/makefiles/buildtree.make Thu Jul 02 11:10:50 2009 -0700 +++ b/make/linux/makefiles/buildtree.make Thu Jul 23 15:53:43 2009 +0100 @@ -63,10 +63,14 @@ # For now, until the compiler is less wobbly: TESTFLAGS = -Xbatch -showversion -ifdef USE_SUNCC -PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH).suncc +ifeq ($(ZERO_BUILD), true) + PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero else -PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH) + ifdef USE_SUNCC + PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH).suncc + else + PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH) + endif endif ifdef FORCE_TIERED @@ -321,6 +325,7 @@ DATA_MODE/sparcv9 = 64 DATA_MODE/amd64 = 64 DATA_MODE/ia64 = 64 +DATA_MODE/zero = $(ZERO_BITSPERWORD) JAVA_FLAG/32 = -d32 JAVA_FLAG/64 = -d64
--- a/make/linux/makefiles/defs.make Thu Jul 02 11:10:50 2009 -0700 +++ b/make/linux/makefiles/defs.make Thu Jul 23 15:53:43 2009 +0100 @@ -37,6 +37,18 @@ ARCH_DATA_MODEL ?= 32 endif +# zero +ifeq ($(ZERO_BUILD), true) + ARCH_DATA_MODEL = $(ZERO_BITSPERWORD) + ifeq ($(ARCH_DATA_MODEL), 64) + MAKE_ARGS += LP64=1 + endif + PLATFORM = linux-zero + VM_PLATFORM = linux_zero + HS_ARCH = zero + ARCH = zero +endif + # ia64 ifeq ($(ARCH), ia64) ARCH_DATA_MODEL = 64 @@ -97,17 +109,19 @@ EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjsig.so EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so -ifeq ($(ARCH_DATA_MODEL), 32) - EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjsig.so - EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so - EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so - EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar -else - ifeq ($(ARCH),ia64) - else - EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so - EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar +ifneq ($(CORE_BUILD), true) + ifeq ($(ARCH_DATA_MODEL), 32) + EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjsig.so + EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so + EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so + EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar + else + ifeq ($(ARCH),ia64) + else + EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so + EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar endif + endif endif
--- a/make/linux/makefiles/gcc.make Thu Jul 02 11:10:50 2009 -0700 +++ b/make/linux/makefiles/gcc.make Thu Jul 23 15:53:43 2009 +0100 @@ -52,6 +52,9 @@ VM_PICFLAG/AOUT = VM_PICFLAG = $(VM_PICFLAG/$(LINK_INTO)) +ifeq ($(ZERO_BUILD), true) +CFLAGS += $(LIBFFI_CFLAGS) +endif CFLAGS += $(VM_PICFLAG) CFLAGS += -fno-rtti CFLAGS += -fno-exceptions @@ -64,6 +67,7 @@ ARCHFLAG/ia64 = ARCHFLAG/sparc = -m32 -mcpu=v9 ARCHFLAG/sparcv9 = -m64 -mcpu=v9 +ARCHFLAG/zero = $(ZERO_ARCHFLAG) CFLAGS += $(ARCHFLAG) AOUT_FLAGS += $(ARCHFLAG)
--- a/make/linux/makefiles/sa.make Thu Jul 02 11:10:50 2009 -0700 +++ b/make/linux/makefiles/sa.make Thu Jul 23 15:53:43 2009 +0100 @@ -52,10 +52,10 @@ SA_PROPERTIES = $(SA_CLASSDIR)/sa.properties # if $(AGENT_DIR) does not exist, we don't build SA -# also, we don't build SA on Itanium. +# also, we don't build SA on Itanium or zero. all: - if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" ] ; then \ + if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" -a "$(SRCARCH)" != "zero" ] ; then \ $(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \ fi
--- a/make/linux/makefiles/saproc.make Thu Jul 02 11:10:50 2009 -0700 +++ b/make/linux/makefiles/saproc.make Thu Jul 23 15:53:43 2009 +0100 @@ -49,10 +49,10 @@ endif # if $(AGENT_DIR) does not exist, we don't build SA -# also, we don't build SA on Itanium. +# also, we don't build SA on Itanium or zero. checkAndBuildSA: - $(QUIETLY) if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" ] ; then \ + $(QUIETLY) if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" -a "$(SRCARCH)" != "zero" ] ; then \ $(MAKE) -f vm.make $(LIBSAPROC); \ fi
--- a/make/linux/makefiles/vm.make Thu Jul 02 11:10:50 2009 -0700 +++ b/make/linux/makefiles/vm.make Thu Jul 23 15:53:43 2009 +0100 @@ -126,6 +126,12 @@ STATIC_CXX = true +ifeq ($(ZERO_LIBARCH), ppc64) + STATIC_CXX = false +else + STATIC_CXX = true +endif + ifeq ($(LINK_INTO),AOUT) LIBJVM.o = LIBJVM_MAPFILE = @@ -148,6 +154,9 @@ LIBS_VM += $(LIBS) endif +ifeq ($(ZERO_BUILD), true) + LIBS_VM += $(LIBFFI_LIBS) +endif LINK_VM = $(LINK_LIB.c)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/linux/makefiles/zero.make Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,41 @@ +# +# Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007, 2008 Red Hat, Inc. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# +# + +# The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized +OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT) +# The copied fdlibm routines in sharedRuntimeTrans.o must not be optimized +OPT_CFLAGS/sharedRuntimeTrans.o = $(OPT_CFLAGS/NOOPT) + +# Specify that the CPU is little endian, if necessary +ifeq ($(ZERO_ENDIANNESS), little) + CFLAGS += -DVM_LITTLE_ENDIAN +endif + +# Specify that the CPU is 64 bit, if necessary +ifeq ($(ZERO_BITSPERWORD), 64) + CFLAGS += -D_LP64=1 +endif + +OPT_CFLAGS/compactingPermGenGen.o = -O1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/linux/platform_zero.in Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,17 @@ +os_family = linux + +arch = zero + +arch_model = zero + +os_arch = linux_zero + +os_arch_model = linux_zero + +lib_arch = zero + +compiler = gcc + +gnu_dis_arch = zero + +sysdefs = -DLINUX -D_GNU_SOURCE -DCC_INTERP -DZERO -D@ZERO_ARCHDEF@ -DZERO_LIBARCH=\"@ZERO_LIBARCH@\"
--- a/make/solaris/makefiles/optimized.make Thu Jul 02 11:10:50 2009 -0700 +++ b/make/solaris/makefiles/optimized.make Thu Jul 23 15:53:43 2009 +0100 @@ -41,7 +41,7 @@ endif # Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12) -ifeq ($(COMPILER_REV_NUMERIC),508)) +ifeq ($(COMPILER_REV_NUMERIC),508) OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2) endif # COMPILER_REV_NUMERIC == 508
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/assembler_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,98 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_assembler_zero.cpp.incl" + +int AbstractAssembler::code_fill_byte() +{ + return 0; +} + +void Assembler::pd_patch_instruction(address branch, address target) +{ + Unimplemented(); +} + +#ifndef PRODUCT +void Assembler::pd_print_patched_instruction(address branch) +{ + Unimplemented(); +} +#endif // PRODUCT + +void MacroAssembler::align(int modulus) +{ + while (offset() % modulus != 0) + emit_byte(AbstractAssembler::code_fill_byte()); +} + +void MacroAssembler::bang_stack_with_offset(int offset) +{ + Unimplemented(); +} + +void MacroAssembler::advance(int bytes) +{ + _code_pos += bytes; + sync(); +} + +RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr, + Register tmpl, int offset) +{ + Unimplemented(); +} + +void MacroAssembler::store_oop(jobject obj) +{ + code_section()->relocate(pc(), oop_Relocation::spec_for_immediate()); + emit_address((address) obj); +} + +static void _UnimplementedStub() +{ + report_unimplemented(__FILE__, __LINE__); +} + +address UnimplementedStub() +{ + return (address) _UnimplementedStub; +} + +address UnimplementedEntry() +{ + return (address) _UnimplementedStub; +} + +static void _ShouldNotReachHereStub() +{ + report_should_not_reach_here(__FILE__, __LINE__); +} + +address ShouldNotReachHereStub() +{ + return (address) _ShouldNotReachHereStub; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/assembler_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,70 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// In normal, CPU-specific ports of HotSpot these two classes are used +// for generating assembly language. We don't do any of this in zero, +// of course, but we do sneak entry points around in CodeBuffers so we +// generate those here. + +class Assembler : public AbstractAssembler { + public: + Assembler(CodeBuffer* code) : AbstractAssembler(code) {} + + void pd_patch_instruction(address branch, address target); +#ifndef PRODUCT + static void pd_print_patched_instruction(address branch); +#endif // PRODUCT +}; + +class MacroAssembler : public Assembler { + public: + MacroAssembler(CodeBuffer* code) : Assembler(code) {} + + void align(int modulus); + void bang_stack_with_offset(int offset); + bool needs_explicit_null_check(intptr_t offset); + RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, + Register tmp, int offset); + public: + void advance(int bytes); + void store_oop(jobject obj); +}; + +#ifdef ASSERT +inline bool AbstractAssembler::pd_check_instruction_mark() +{ + Unimplemented(); +} +#endif + +address UnimplementedStub(); +address UnimplementedEntry(); +address ShouldNotReachHereStub(); + +// Nothing to do with the assembler (or lack of), +// just a real convenient place to include these. +#include <ffi.h> +#include <entry_zero.hpp> +#include <stack_zero.hpp>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/assembler_zero.inline.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/bytecodeInterpreter_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,55 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_cppInterpreter_zero.cpp.incl" + +#ifdef CC_INTERP + +const char *BytecodeInterpreter::name_of_field_at_address(address addr) +{ +#define DO(member) {if (addr == (address) &(member)) return XSTR(member);} + DO(_thread); + DO(_bcp); + DO(_locals); + DO(_constants); + DO(_method); + DO(_mdx); + DO(_stack); + DO(_msg); + DO(_result); + DO(_prev_link); + DO(_oop_temp); + DO(_stack_base); + DO(_stack_limit); + DO(_monitor_base); + DO(_self_link); +#undef DO + if (addr > (address) &_result && addr < (address) (&_result + 1)) + return "_result)"; + return NULL; +} + +#endif // CC_INTERP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/bytecodeInterpreter_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,159 @@ +/* + * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Platform specific for C++ based Interpreter + +#if defined(PPC) || defined(SPARC) || defined(IA64) +#define LOTS_OF_REGS // Use plenty of registers +#else +#undef LOTS_OF_REGS // Loser platforms +#endif + + private: + interpreterState _self_link; + + public: + inline void set_locals(intptr_t* new_locals) + { + _locals = new_locals; + } + inline void set_method(methodOop new_method) + { + _method = new_method; + } + inline interpreterState self_link() + { + return _self_link; + } + inline void set_self_link(interpreterState new_self_link) + { + _self_link = new_self_link; + } + inline interpreterState prev_link() + { + return _prev_link; + } + inline void set_prev_link(interpreterState new_prev_link) + { + _prev_link = new_prev_link; + } + inline void set_stack_limit(intptr_t* new_stack_limit) + { + _stack_limit = new_stack_limit; + } + inline void set_stack_base(intptr_t* new_stack_base) + { + _stack_base = new_stack_base; + } + inline void set_monitor_base(BasicObjectLock *new_monitor_base) + { + _monitor_base = new_monitor_base; + } + inline void set_thread(JavaThread* new_thread) + { + _thread = new_thread; + } + inline void set_constants(constantPoolCacheOop new_constants) + { + _constants = new_constants; + } + inline oop oop_temp() + { + return _oop_temp; + } + inline oop *oop_temp_addr() + { + return &_oop_temp; + } + inline void set_oop_temp(oop new_oop_temp) + { + _oop_temp = new_oop_temp; + } + inline address callee_entry_point() + { + return _result._to_call._callee_entry_point; + } + + public: + const char *name_of_field_at_address(address addr); + +// The frame manager handles this +#define SET_LAST_JAVA_FRAME() +#define RESET_LAST_JAVA_FRAME() + +// ZeroStack Implementation + +#undef STACK_INT +#undef STACK_FLOAT +#undef STACK_ADDR +#undef STACK_OBJECT +#undef STACK_DOUBLE +#undef STACK_LONG + +#define GET_STACK_SLOT(offset) (*((intptr_t*) &topOfStack[-(offset)])) +#define STACK_SLOT(offset) ((address) &topOfStack[-(offset)]) +#define STACK_ADDR(offset) (*((address *) &topOfStack[-(offset)])) +#define STACK_INT(offset) (*((jint*) &topOfStack[-(offset)])) +#define STACK_FLOAT(offset) (*((jfloat *) &topOfStack[-(offset)])) +#define STACK_OBJECT(offset) (*((oop *) &topOfStack [-(offset)])) +#define STACK_DOUBLE(offset) (((VMJavaVal64*) &topOfStack[-(offset)])->d) +#define STACK_LONG(offset) (((VMJavaVal64 *) &topOfStack[-(offset)])->l) + +#define SET_STACK_SLOT(value, offset) (*(intptr_t*)&topOfStack[-(offset)] = *(intptr_t*)(value)) +#define SET_STACK_ADDR(value, offset) (*((address *)&topOfStack[-(offset)]) = (value)) +#define SET_STACK_INT(value, offset) (*((jint *)&topOfStack[-(offset)]) = (value)) +#define SET_STACK_FLOAT(value, offset) (*((jfloat *)&topOfStack[-(offset)]) = (value)) +#define SET_STACK_OBJECT(value, offset) (*((oop *)&topOfStack[-(offset)]) = (value)) +#define SET_STACK_DOUBLE(value, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->d = (value)) +#define SET_STACK_DOUBLE_FROM_ADDR(addr, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->d = \ + ((VMJavaVal64*)(addr))->d) +#define SET_STACK_LONG(value, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->l = (value)) +#define SET_STACK_LONG_FROM_ADDR(addr, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->l = \ + ((VMJavaVal64*)(addr))->l) +// JavaLocals implementation + +#define LOCALS_SLOT(offset) ((intptr_t*)&locals[-(offset)]) +#define LOCALS_ADDR(offset) ((address)locals[-(offset)]) +#define LOCALS_INT(offset) (*((jint*)&locals[-(offset)])) +#define LOCALS_FLOAT(offset) (*((jfloat*)&locals[-(offset)])) +#define LOCALS_OBJECT(offset) ((oop)locals[-(offset)]) +#define LOCALS_DOUBLE(offset) (((VMJavaVal64*)&locals[-((offset) + 1)])->d) +#define LOCALS_LONG(offset) (((VMJavaVal64*)&locals[-((offset) + 1)])->l) +#define LOCALS_LONG_AT(offset) (((address)&locals[-((offset) + 1)])) +#define LOCALS_DOUBLE_AT(offset) (((address)&locals[-((offset) + 1)])) + +#define SET_LOCALS_SLOT(value, offset) (*(intptr_t*)&locals[-(offset)] = *(intptr_t *)(value)) +#define SET_LOCALS_ADDR(value, offset) (*((address *)&locals[-(offset)]) = (value)) +#define SET_LOCALS_INT(value, offset) (*((jint *)&locals[-(offset)]) = (value)) +#define SET_LOCALS_FLOAT(value, offset) (*((jfloat *)&locals[-(offset)]) = (value)) +#define SET_LOCALS_OBJECT(value, offset) (*((oop *)&locals[-(offset)]) = (value)) +#define SET_LOCALS_DOUBLE(value, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->d = (value)) +#define SET_LOCALS_LONG(value, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->l = (value)) +#define SET_LOCALS_DOUBLE_FROM_ADDR(addr, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->d = \ + ((VMJavaVal64*)(addr))->d) +#define SET_LOCALS_LONG_FROM_ADDR(addr, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->l = \ + ((VMJavaVal64*)(addr))->l) + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/bytecodeInterpreter_zero.inline.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,280 @@ +/* + * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Inline interpreter functions for zero + +inline jfloat BytecodeInterpreter::VMfloatAdd(jfloat op1, jfloat op2) { return op1 + op2; } +inline jfloat BytecodeInterpreter::VMfloatSub(jfloat op1, jfloat op2) { return op1 - op2; } +inline jfloat BytecodeInterpreter::VMfloatMul(jfloat op1, jfloat op2) { return op1 * op2; } +inline jfloat BytecodeInterpreter::VMfloatDiv(jfloat op1, jfloat op2) { return op1 / op2; } +inline jfloat BytecodeInterpreter::VMfloatRem(jfloat op1, jfloat op2) { return fmod(op1, op2); } + +inline jfloat BytecodeInterpreter::VMfloatNeg(jfloat op) { return -op; } + +inline int32_t BytecodeInterpreter::VMfloatCompare(jfloat op1, jfloat op2, int32_t direction) { + return ( op1 < op2 ? -1 : + op1 > op2 ? 1 : + op1 == op2 ? 0 : + (direction == -1 || direction == 1) ? direction : 0); + +} + +inline void BytecodeInterpreter::VMmemCopy64(uint32_t to[2], const uint32_t from[2]) { + *(uint64_t *) to = *(uint64_t *) from; +} + +inline jlong BytecodeInterpreter::VMlongAdd(jlong op1, jlong op2) { + return op1 + op2; +} + +inline jlong BytecodeInterpreter::VMlongAnd(jlong op1, jlong op2) { + return op1 & op2; +} + +inline jlong BytecodeInterpreter::VMlongDiv(jlong op1, jlong op2) { + /* it's possible we could catch this special case implicitly */ + if (op1 == (jlong) 0x8000000000000000LL && op2 == -1) return op1; + else return op1 / op2; +} + +inline jlong BytecodeInterpreter::VMlongMul(jlong op1, jlong op2) { + return op1 * op2; +} + +inline jlong BytecodeInterpreter::VMlongOr(jlong op1, jlong op2) { + return op1 | op2; +} + +inline jlong BytecodeInterpreter::VMlongSub(jlong op1, jlong op2) { + return op1 - op2; +} + +inline jlong BytecodeInterpreter::VMlongXor(jlong op1, jlong op2) { + return op1 ^ op2; +} + +inline jlong BytecodeInterpreter::VMlongRem(jlong op1, jlong op2) { + /* it's possible we could catch this special case implicitly */ + if (op1 == (jlong) 0x8000000000000000LL && op2 == -1) return 0; + else return op1 % op2; +} + +inline jlong BytecodeInterpreter::VMlongUshr(jlong op1, jint op2) { + return ((unsigned long long) op1) >> (op2 & 0x3F); +} + +inline jlong BytecodeInterpreter::VMlongShr(jlong op1, jint op2) { + return op1 >> (op2 & 0x3F); +} + +inline jlong BytecodeInterpreter::VMlongShl(jlong op1, jint op2) { + return op1 << (op2 & 0x3F); +} + +inline jlong BytecodeInterpreter::VMlongNeg(jlong op) { + return -op; +} + +inline jlong BytecodeInterpreter::VMlongNot(jlong op) { + return ~op; +} + +inline int32_t BytecodeInterpreter::VMlongLtz(jlong op) { + return (op <= 0); +} + +inline int32_t BytecodeInterpreter::VMlongGez(jlong op) { + return (op >= 0); +} + +inline int32_t BytecodeInterpreter::VMlongEqz(jlong op) { + return (op == 0); +} + +inline int32_t BytecodeInterpreter::VMlongEq(jlong op1, jlong op2) { + return (op1 == op2); +} + +inline int32_t BytecodeInterpreter::VMlongNe(jlong op1, jlong op2) { + return (op1 != op2); +} + +inline int32_t BytecodeInterpreter::VMlongGe(jlong op1, jlong op2) { + return (op1 >= op2); +} + +inline int32_t BytecodeInterpreter::VMlongLe(jlong op1, jlong op2) { + return (op1 <= op2); +} + +inline int32_t BytecodeInterpreter::VMlongLt(jlong op1, jlong op2) { + return (op1 < op2); +} + +inline int32_t BytecodeInterpreter::VMlongGt(jlong op1, jlong op2) { + return (op1 > op2); +} + +inline int32_t BytecodeInterpreter::VMlongCompare(jlong op1, jlong op2) { + return (VMlongLt(op1, op2) ? -1 : VMlongGt(op1, op2) ? 1 : 0); +} + +// Long conversions + +inline jdouble BytecodeInterpreter::VMlong2Double(jlong val) { + return (jdouble) val; +} + +inline jfloat BytecodeInterpreter::VMlong2Float(jlong val) { + return (jfloat) val; +} + +inline jint BytecodeInterpreter::VMlong2Int(jlong val) { + return (jint) val; +} + +// Double Arithmetic + +inline jdouble BytecodeInterpreter::VMdoubleAdd(jdouble op1, jdouble op2) { + return op1 + op2; +} + +inline jdouble BytecodeInterpreter::VMdoubleDiv(jdouble op1, jdouble op2) { + // Divide by zero... QQQ + return op1 / op2; +} + +inline jdouble BytecodeInterpreter::VMdoubleMul(jdouble op1, jdouble op2) { + return op1 * op2; +} + +inline jdouble BytecodeInterpreter::VMdoubleNeg(jdouble op) { + return -op; +} + +inline jdouble BytecodeInterpreter::VMdoubleRem(jdouble op1, jdouble op2) { + return fmod(op1, op2); +} + +inline jdouble BytecodeInterpreter::VMdoubleSub(jdouble op1, jdouble op2) { + return op1 - op2; +} + +inline int32_t BytecodeInterpreter::VMdoubleCompare(jdouble op1, jdouble op2, int32_t direction) { + return ( op1 < op2 ? -1 : + op1 > op2 ? 1 : + op1 == op2 ? 0 : + (direction == -1 || direction == 1) ? direction : 0); +} + +// Double Conversions + +inline jfloat BytecodeInterpreter::VMdouble2Float(jdouble val) { + return (jfloat) val; +} + +// Float Conversions + +inline jdouble BytecodeInterpreter::VMfloat2Double(jfloat op) { + return (jdouble) op; +} + +// Integer Arithmetic + +inline jint BytecodeInterpreter::VMintAdd(jint op1, jint op2) { + return op1 + op2; +} + +inline jint BytecodeInterpreter::VMintAnd(jint op1, jint op2) { + return op1 & op2; +} + +inline jint BytecodeInterpreter::VMintDiv(jint op1, jint op2) { + /* it's possible we could catch this special case implicitly */ + if (op1 == (jint) 0x80000000 && op2 == -1) return op1; + else return op1 / op2; +} + +inline jint BytecodeInterpreter::VMintMul(jint op1, jint op2) { + return op1 * op2; +} + +inline jint BytecodeInterpreter::VMintNeg(jint op) { + return -op; +} + +inline jint BytecodeInterpreter::VMintOr(jint op1, jint op2) { + return op1 | op2; +} + +inline jint BytecodeInterpreter::VMintRem(jint op1, jint op2) { + /* it's possible we could catch this special case implicitly */ + if (op1 == (jint) 0x80000000 && op2 == -1) return 0; + else return op1 % op2; +} + +inline jint BytecodeInterpreter::VMintShl(jint op1, jint op2) { + return op1 << (op2 & 0x1F); +} + +inline jint BytecodeInterpreter::VMintShr(jint op1, jint op2) { + return op1 >> (op2 & 0x1F); +} + +inline jint BytecodeInterpreter::VMintSub(jint op1, jint op2) { + return op1 - op2; +} + +inline jint BytecodeInterpreter::VMintUshr(jint op1, jint op2) { + return ((juint) op1) >> (op2 & 0x1F); +} + +inline jint BytecodeInterpreter::VMintXor(jint op1, jint op2) { + return op1 ^ op2; +} + +inline jdouble BytecodeInterpreter::VMint2Double(jint val) { + return (jdouble) val; +} + +inline jfloat BytecodeInterpreter::VMint2Float(jint val) { + return (jfloat) val; +} + +inline jlong BytecodeInterpreter::VMint2Long(jint val) { + return (jlong) val; +} + +inline jchar BytecodeInterpreter::VMint2Char(jint val) { + return (jchar) val; +} + +inline jshort BytecodeInterpreter::VMint2Short(jint val) { + return (jshort) val; +} + +inline jbyte BytecodeInterpreter::VMint2Byte(jint val) { + return (jbyte) val; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/bytecodes_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_bytecodes_zero.cpp.incl" + +void Bytecodes::pd_initialize() +{ + // No zero specific initialization +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/bytecodes_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/bytes_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,307 @@ +/* + * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class Bytes: AllStatic { + public: + // Returns true if the byte ordering used by Java is different + // from the native byte ordering of the underlying machine. + static inline bool is_Java_byte_ordering_different() + { +#ifdef VM_LITTLE_ENDIAN + return true; +#else + return false; +#endif + } + + // Efficient reading and writing of unaligned unsigned data in + // platform-specific byte ordering. +#ifdef VM_LITTLE_ENDIAN + static inline u2 get_native_u2(address p){ + return (intptr_t(p) & 1) == 0 + ? *(u2*)p + : ( u2(p[1]) << 8 ) + | ( u2(p[0]) ); + } + + static inline u4 get_native_u4(address p) { + switch (intptr_t(p) & 3) { + case 0: return *(u4*)p; + + case 2: return ( u4( ((u2*)p)[1] ) << 16 ) + | ( u4( ((u2*)p)[0] ) ); + + default: return ( u4(p[3]) << 24 ) + | ( u4(p[2]) << 16 ) + | ( u4(p[1]) << 8 ) + | u4(p[0]); + } + } + + static inline u8 get_native_u8(address p) { + switch (intptr_t(p) & 7) { + case 0: return *(u8*)p; + + case 4: return ( u8( ((u4*)p)[1] ) << 32 ) + | ( u8( ((u4*)p)[0] ) ); + + case 2: return ( u8( ((u2*)p)[3] ) << 48 ) + | ( u8( ((u2*)p)[2] ) << 32 ) + | ( u8( ((u2*)p)[1] ) << 16 ) + | ( u8( ((u2*)p)[0] ) ); + + default: return ( u8(p[7]) << 56 ) + | ( u8(p[6]) << 48 ) + | ( u8(p[5]) << 40 ) + | ( u8(p[4]) << 32 ) + | ( u8(p[3]) << 24 ) + | ( u8(p[2]) << 16 ) + | ( u8(p[1]) << 8 ) + | u8(p[0]); + } + } + + static inline void put_native_u2(address p, u2 x) { + if ( (intptr_t(p) & 1) == 0 ) *(u2*)p = x; + else { + p[1] = x >> 8; + p[0] = x; + } + } + + static inline void put_native_u4(address p, u4 x) { + switch ( intptr_t(p) & 3 ) { + case 0: *(u4*)p = x; + break; + + case 2: ((u2*)p)[1] = x >> 16; + ((u2*)p)[0] = x; + break; + + default: ((u1*)p)[3] = x >> 24; + ((u1*)p)[2] = x >> 16; + ((u1*)p)[1] = x >> 8; + ((u1*)p)[0] = x; + break; + } + } + + static inline void put_native_u8(address p, u8 x) { + switch ( intptr_t(p) & 7 ) { + case 0: *(u8*)p = x; + break; + + case 4: ((u4*)p)[1] = x >> 32; + ((u4*)p)[0] = x; + break; + + case 2: ((u2*)p)[3] = x >> 48; + ((u2*)p)[2] = x >> 32; + ((u2*)p)[1] = x >> 16; + ((u2*)p)[0] = x; + break; + + default: ((u1*)p)[7] = x >> 56; + ((u1*)p)[6] = x >> 48; + ((u1*)p)[5] = x >> 40; + ((u1*)p)[4] = x >> 32; + ((u1*)p)[3] = x >> 24; + ((u1*)p)[2] = x >> 16; + ((u1*)p)[1] = x >> 8; + ((u1*)p)[0] = x; + } + } +#else + static inline u2 get_native_u2(address p){ + return (intptr_t(p) & 1) == 0 + ? *(u2*)p + : ( u2(p[0]) << 8 ) + | ( u2(p[1]) ); + } + + static inline u4 get_native_u4(address p) { + switch (intptr_t(p) & 3) { + case 0: return *(u4*)p; + + case 2: return ( u4( ((u2*)p)[0] ) << 16 ) + | ( u4( ((u2*)p)[1] ) ); + + default: return ( u4(p[0]) << 24 ) + | ( u4(p[1]) << 16 ) + | ( u4(p[2]) << 8 ) + | u4(p[3]); + } + } + + static inline u8 get_native_u8(address p) { + switch (intptr_t(p) & 7) { + case 0: return *(u8*)p; + + case 4: return ( u8( ((u4*)p)[0] ) << 32 ) + | ( u8( ((u4*)p)[1] ) ); + + case 2: return ( u8( ((u2*)p)[0] ) << 48 ) + | ( u8( ((u2*)p)[1] ) << 32 ) + | ( u8( ((u2*)p)[2] ) << 16 ) + | ( u8( ((u2*)p)[3] ) ); + + default: return ( u8(p[0]) << 56 ) + | ( u8(p[1]) << 48 ) + | ( u8(p[2]) << 40 ) + | ( u8(p[3]) << 32 ) + | ( u8(p[4]) << 24 ) + | ( u8(p[5]) << 16 ) + | ( u8(p[6]) << 8 ) + | u8(p[7]); + } + } + + static inline void put_native_u2(address p, u2 x) { + if ( (intptr_t(p) & 1) == 0 ) *(u2*)p = x; + else { + p[0] = x >> 8; + p[1] = x; + } + } + + static inline void put_native_u4(address p, u4 x) { + switch ( intptr_t(p) & 3 ) { + case 0: *(u4*)p = x; + break; + + case 2: ((u2*)p)[0] = x >> 16; + ((u2*)p)[1] = x; + break; + + default: ((u1*)p)[0] = x >> 24; + ((u1*)p)[1] = x >> 16; + ((u1*)p)[2] = x >> 8; + ((u1*)p)[3] = x; + break; + } + } + + static inline void put_native_u8(address p, u8 x) { + switch ( intptr_t(p) & 7 ) { + case 0: *(u8*)p = x; + break; + + case 4: ((u4*)p)[0] = x >> 32; + ((u4*)p)[1] = x; + break; + + case 2: ((u2*)p)[0] = x >> 48; + ((u2*)p)[1] = x >> 32; + ((u2*)p)[2] = x >> 16; + ((u2*)p)[3] = x; + break; + + default: ((u1*)p)[0] = x >> 56; + ((u1*)p)[1] = x >> 48; + ((u1*)p)[2] = x >> 40; + ((u1*)p)[3] = x >> 32; + ((u1*)p)[4] = x >> 24; + ((u1*)p)[5] = x >> 16; + ((u1*)p)[6] = x >> 8; + ((u1*)p)[7] = x; + } + } +#endif // VM_LITTLE_ENDIAN + + + // Efficient reading and writing of unaligned unsigned data in Java + // byte ordering (i.e. big-endian ordering). +#ifdef VM_LITTLE_ENDIAN + // Byte-order reversal is needed + static inline u2 get_Java_u2(address p) + { + return swap_u2(get_native_u2(p)); + } + static inline u4 get_Java_u4(address p) + { + return swap_u4(get_native_u4(p)); + } + static inline u8 get_Java_u8(address p) + { + return swap_u8(get_native_u8(p)); + } + + static inline void put_Java_u2(address p, u2 x) + { + put_native_u2(p, swap_u2(x)); + } + static inline void put_Java_u4(address p, u4 x) + { + put_native_u4(p, swap_u4(x)); + } + static inline void put_Java_u8(address p, u8 x) + { + put_native_u8(p, swap_u8(x)); + } + + // Efficient swapping of byte ordering + static inline u2 swap_u2(u2 x); + static inline u4 swap_u4(u4 x); + static inline u8 swap_u8(u8 x); +#else + // No byte-order reversal is needed + static inline u2 get_Java_u2(address p) + { + return get_native_u2(p); + } + static inline u4 get_Java_u4(address p) + { + return get_native_u4(p); + } + static inline u8 get_Java_u8(address p) + { + return get_native_u8(p); + } + + static inline void put_Java_u2(address p, u2 x) + { + put_native_u2(p, x); + } + static inline void put_Java_u4(address p, u4 x) + { + put_native_u4(p, x); + } + static inline void put_Java_u8(address p, u8 x) + { + put_native_u8(p, x); + } + + // No byte-order reversal is needed + static inline u2 swap_u2(u2 x) { return x; } + static inline u4 swap_u4(u4 x) { return x; } + static inline u8 swap_u8(u8 x) { return x; } +#endif // VM_LITTLE_ENDIAN +}; + +#ifdef VM_LITTLE_ENDIAN +// The following header contains the implementations of swap_u2, +// swap_u4, and swap_u8 +#include "incls/_bytes_pd.inline.hpp.incl" +#endif // VM_LITTLE_ENDIAN
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/codeBuffer_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,27 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +private: + void pd_initialize() {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/copy_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,166 @@ +/* + * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Inline functions for memory copy and fill. + +static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) { + (void)memmove(to, from, count * HeapWordSize); +} + +static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) { + switch (count) { + case 8: to[7] = from[7]; + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + default: + (void)memcpy(to, from, count * HeapWordSize); + break; + } +} + +static void pd_disjoint_words_atomic(HeapWord* from, + HeapWord* to, + size_t count) { + switch (count) { + case 8: to[7] = from[7]; + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + default: + while (count-- > 0) { + *to++ = *from++; + } + break; + } +} + +static void pd_aligned_conjoint_words(HeapWord* from, + HeapWord* to, + size_t count) { + (void)memmove(to, from, count * HeapWordSize); +} + +static void pd_aligned_disjoint_words(HeapWord* from, + HeapWord* to, + size_t count) { + pd_disjoint_words(from, to, count); +} + +static void pd_conjoint_bytes(void* from, void* to, size_t count) { + (void)memmove(to, from, count); +} + +static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) { + (void)memmove(to, from, count); +} + +static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) { + _Copy_conjoint_jshorts_atomic(from, to, count); +} + +static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) { + _Copy_conjoint_jints_atomic(from, to, count); +} + +static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) { + _Copy_conjoint_jlongs_atomic(from, to, count); +} + +static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) { +#ifdef _LP64 + assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); + _Copy_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count); +#else + assert(BytesPerInt == BytesPerOop, "jints and oops must be the same size"); + _Copy_conjoint_jints_atomic((jint*)from, (jint*)to, count); +#endif // _LP64 +} + +static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_bytes(from, to, count); +} + +static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_jshorts(from, to, count); +} + +static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_jints(from, to, count); +} + +static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) { + _Copy_arrayof_conjoint_jlongs(from, to, count); +} + +static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) { +#ifdef _LP64 + assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size"); + _Copy_arrayof_conjoint_jlongs(from, to, count); +#else + assert(BytesPerInt == BytesPerOop, "jints and oops must be the same size"); + _Copy_arrayof_conjoint_jints(from, to, count); +#endif // _LP64 +} + +static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) { +#ifdef _LP64 + julong* to = (julong*) tohw; + julong v = ((julong) value << 32) | value; +#else + juint* to = (juint*) tohw; + juint v = value; +#endif // _LP64 + + while (count-- > 0) { + *to++ = v; + } +} + +static void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) { + pd_fill_to_words(tohw, count, value); +} + +static void pd_fill_to_bytes(void* to, size_t count, jubyte value) { + (void)memset(to, value, count); +} + +static void pd_zero_to_words(HeapWord* tohw, size_t count) { + pd_fill_to_words(tohw, count, 0); +} + +static void pd_zero_to_bytes(void* to, size_t count) { + (void)memset(to, 0, count); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,39 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + protected: + MacroAssembler* assembler() const + { + return _masm; + } + + protected: + address generate_entry(ZeroEntry::method_entry_t entry_point) + { + ZeroEntry *entry = (ZeroEntry *) assembler()->pc(); + assembler()->advance(sizeof(ZeroEntry)); + entry->set_entry_point(entry_point); + return (address) entry; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,956 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_cppInterpreter_zero.cpp.incl" + +#ifdef CC_INTERP + +#define fixup_after_potential_safepoint() \ + method = istate->method() + +#define CALL_VM_NOCHECK(func) \ + thread->set_last_Java_frame(); \ + func; \ + thread->reset_last_Java_frame(); \ + fixup_after_potential_safepoint() + +void CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) +{ + JavaThread *thread = (JavaThread *) THREAD; + ZeroStack *stack = thread->zero_stack(); + + // Adjust the caller's stack frame to accomodate any additional + // local variables we have contiguously with our parameters. + int extra_locals = method->max_locals() - method->size_of_parameters(); + if (extra_locals > 0) { + if (extra_locals > stack->available_words()) { + Unimplemented(); + } + for (int i = 0; i < extra_locals; i++) + stack->push(0); + } + + // Allocate and initialize our frame. + InterpreterFrame *frame = InterpreterFrame::build(stack, method, thread); + thread->push_zero_frame(frame); + + // Execute those bytecodes! + main_loop(0, THREAD); +} + +void CppInterpreter::main_loop(int recurse, TRAPS) +{ + JavaThread *thread = (JavaThread *) THREAD; + ZeroStack *stack = thread->zero_stack(); + + // If we are entering from a deopt we may need to call + // ourself a few times in order to get to our frame. + if (recurse) + main_loop(recurse - 1, THREAD); + + InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame(); + interpreterState istate = frame->interpreter_state(); + methodOop method = istate->method(); + + intptr_t *result = NULL; + int result_slots = 0; + + // Check we're not about to run out of stack + if (stack_overflow_imminent(thread)) { + CALL_VM_NOCHECK(InterpreterRuntime::throw_StackOverflowError(thread)); + goto unwind_and_return; + } + + while (true) { + // We can set up the frame anchor with everything we want at + // this point as we are thread_in_Java and no safepoints can + // occur until we go to vm mode. We do have to clear flags + // on return from vm but that is it. + thread->set_last_Java_frame(); + + // Call the interpreter + if (JvmtiExport::can_post_interpreter_events()) + BytecodeInterpreter::runWithChecks(istate); + else + BytecodeInterpreter::run(istate); + fixup_after_potential_safepoint(); + + // Clear the frame anchor + thread->reset_last_Java_frame(); + + // Examine the message from the interpreter to decide what to do + if (istate->msg() == BytecodeInterpreter::call_method) { + methodOop callee = istate->callee(); + + // Trim back the stack to put the parameters at the top + stack->set_sp(istate->stack() + 1); + + // Make the call + Interpreter::invoke_method(callee, istate->callee_entry_point(), THREAD); + fixup_after_potential_safepoint(); + + // Convert the result + istate->set_stack(stack->sp() - 1); + + // Restore the stack + stack->set_sp(istate->stack_limit() + 1); + + // Resume the interpreter + istate->set_msg(BytecodeInterpreter::method_resume); + } + else if (istate->msg() == BytecodeInterpreter::more_monitors) { + int monitor_words = frame::interpreter_frame_monitor_size(); + + // Allocate the space + if (monitor_words > stack->available_words()) { + Unimplemented(); + } + stack->alloc(monitor_words * wordSize); + + // Move the expression stack contents + for (intptr_t *p = istate->stack() + 1; p < istate->stack_base(); p++) + *(p - monitor_words) = *p; + + // Move the expression stack pointers + istate->set_stack_limit(istate->stack_limit() - monitor_words); + istate->set_stack(istate->stack() - monitor_words); + istate->set_stack_base(istate->stack_base() - monitor_words); + + // Zero the new monitor so the interpreter can find it. + ((BasicObjectLock *) istate->stack_base())->set_obj(NULL); + + // Resume the interpreter + istate->set_msg(BytecodeInterpreter::got_monitors); + } + else if (istate->msg() == BytecodeInterpreter::return_from_method) { + // Copy the result into the caller's frame + result_slots = type2size[method->result_type()]; + assert(result_slots >= 0 && result_slots <= 2, "what?"); + result = istate->stack() + result_slots; + break; + } + else if (istate->msg() == BytecodeInterpreter::throwing_exception) { + assert(HAS_PENDING_EXCEPTION, "should do"); + break; + } + else { + ShouldNotReachHere(); + } + } + + unwind_and_return: + + // Unwind the current frame + thread->pop_zero_frame(); + + // Pop our local variables + stack->set_sp(stack->sp() + method->max_locals()); + + // Push our result + for (int i = 0; i < result_slots; i++) + stack->push(result[-i]); +} + +void CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) +{ + // Make sure method is native and not abstract + assert(method->is_native() && !method->is_abstract(), "should be"); + + JavaThread *thread = (JavaThread *) THREAD; + ZeroStack *stack = thread->zero_stack(); + + // Allocate and initialize our frame + InterpreterFrame *frame = InterpreterFrame::build(stack, method, thread); + thread->push_zero_frame(frame); + interpreterState istate = frame->interpreter_state(); + intptr_t *locals = istate->locals(); + + // Check we're not about to run out of stack + if (stack_overflow_imminent(thread)) { + CALL_VM_NOCHECK(InterpreterRuntime::throw_StackOverflowError(thread)); + goto unwind_and_return; + } + + // Lock if necessary + BasicObjectLock *monitor; + monitor = NULL; + if (method->is_synchronized()) { + monitor = (BasicObjectLock*) istate->stack_base(); + oop lockee = monitor->obj(); + markOop disp = lockee->mark()->set_unlocked(); + + monitor->lock()->set_displaced_header(disp); + if (Atomic::cmpxchg_ptr(monitor, lockee->mark_addr(), disp) != disp) { + if (thread->is_lock_owned((address) disp->clear_lock_bits())) { + monitor->lock()->set_displaced_header(NULL); + } + else { + CALL_VM_NOCHECK(InterpreterRuntime::monitorenter(thread, monitor)); + if (HAS_PENDING_EXCEPTION) + goto unwind_and_return; + } + } + } + + // Get the signature handler + InterpreterRuntime::SignatureHandler *handler; + { + address handlerAddr = method->signature_handler(); + if (handlerAddr == NULL) { + CALL_VM_NOCHECK(InterpreterRuntime::prepare_native_call(thread, method)); + if (HAS_PENDING_EXCEPTION) + goto unwind_and_return; + + handlerAddr = method->signature_handler(); + assert(handlerAddr != NULL, "eh?"); + } + if (handlerAddr == (address) InterpreterRuntime::slow_signature_handler) { + CALL_VM_NOCHECK(handlerAddr = + InterpreterRuntime::slow_signature_handler(thread, method, NULL,NULL)); + if (HAS_PENDING_EXCEPTION) + goto unwind_and_return; + } + handler = \ + InterpreterRuntime::SignatureHandler::from_handlerAddr(handlerAddr); + } + + // Get the native function entry point + address function; + function = method->native_function(); + assert(function != NULL, "should be set if signature handler is"); + + // Build the argument list + if (handler->argument_count() * 2 > stack->available_words()) { + Unimplemented(); + } + void **arguments; + { + arguments = + (void **) stack->alloc(handler->argument_count() * sizeof(void **)); + void **dst = arguments; + + void *env = thread->jni_environment(); + *(dst++) = &env; + + void *mirror = NULL; + if (method->is_static()) { + istate->set_oop_temp( + method->constants()->pool_holder()->klass_part()->java_mirror()); + mirror = istate->oop_temp_addr(); + *(dst++) = &mirror; + } + + intptr_t *src = locals; + for (int i = dst - arguments; i < handler->argument_count(); i++) { + ffi_type *type = handler->argument_type(i); + if (type == &ffi_type_pointer) { + if (*src) { + stack->push((intptr_t) src); + *(dst++) = stack->sp(); + } + else { + *(dst++) = src; + } + src--; + } + else if (type->size == 4) { + *(dst++) = src--; + } + else if (type->size == 8) { + src--; + *(dst++) = src--; + } + else { + ShouldNotReachHere(); + } + } + } + + // Set up the Java frame anchor + thread->set_last_Java_frame(); + + // Change the thread state to _thread_in_native + ThreadStateTransition::transition_from_java(thread, _thread_in_native); + + // Make the call + intptr_t result[4 - LogBytesPerWord]; + ffi_call(handler->cif(), (void (*)()) function, result, arguments); + + // Change the thread state back to _thread_in_Java. + // ThreadStateTransition::transition_from_native() cannot be used + // here because it does not check for asynchronous exceptions. + // We have to manage the transition ourself. + thread->set_thread_state(_thread_in_native_trans); + + // Make sure new state is visible in the GC thread + if (os::is_MP()) { + if (UseMembar) { + OrderAccess::fence(); + } + else { + InterfaceSupport::serialize_memory(thread); + } + } + + // Handle safepoint operations, pending suspend requests, + // and pending asynchronous exceptions. + if (SafepointSynchronize::do_call_back() || + thread->has_special_condition_for_native_trans()) { + JavaThread::check_special_condition_for_native_trans(thread); + CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops()); + } + + // Finally we can change the thread state to _thread_in_Java. + thread->set_thread_state(_thread_in_Java); + fixup_after_potential_safepoint(); + + // Clear the frame anchor + thread->reset_last_Java_frame(); + + // If the result was an oop then unbox it and store it in + // oop_temp where the garbage collector can see it before + // we release the handle it might be protected by. + if (handler->result_type() == &ffi_type_pointer) { + if (result[0]) + istate->set_oop_temp(*(oop *) result[0]); + else + istate->set_oop_temp(NULL); + } + + // Reset handle block + thread->active_handles()->clear(); + + // Unlock if necessary. It seems totally wrong that this + // is skipped in the event of an exception but apparently + // the template interpreter does this so we do too. + if (monitor && !HAS_PENDING_EXCEPTION) { + BasicLock *lock = monitor->lock(); + markOop header = lock->displaced_header(); + oop rcvr = monitor->obj(); + monitor->set_obj(NULL); + + if (header != NULL) { + if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), lock) != lock) { + monitor->set_obj(rcvr); + { + HandleMark hm(thread); + CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(thread, monitor)); + } + } + } + } + + unwind_and_return: + + // Unwind the current activation + thread->pop_zero_frame(); + + // Pop our parameters + stack->set_sp(stack->sp() + method->size_of_parameters()); + + // Push our result + if (!HAS_PENDING_EXCEPTION) { + stack->set_sp(stack->sp() - type2size[method->result_type()]); + + switch (method->result_type()) { + case T_VOID: + break; + + case T_BOOLEAN: +#ifndef VM_LITTLE_ENDIAN + result[0] <<= (BitsPerWord - BitsPerByte); +#endif + SET_LOCALS_INT(*(jboolean *) result != 0, 0); + break; + + case T_CHAR: +#ifndef VM_LITTLE_ENDIAN + result[0] <<= (BitsPerWord - BitsPerShort); +#endif + SET_LOCALS_INT(*(jchar *) result, 0); + break; + + case T_BYTE: +#ifndef VM_LITTLE_ENDIAN + result[0] <<= (BitsPerWord - BitsPerByte); +#endif + SET_LOCALS_INT(*(jbyte *) result, 0); + break; + + case T_SHORT: +#ifndef VM_LITTLE_ENDIAN + result[0] <<= (BitsPerWord - BitsPerShort); +#endif + SET_LOCALS_INT(*(jshort *) result, 0); + break; + + case T_INT: +#ifndef VM_LITTLE_ENDIAN + result[0] <<= (BitsPerWord - BitsPerInt); +#endif + SET_LOCALS_INT(*(jint *) result, 0); + break; + + case T_LONG: + SET_LOCALS_LONG(*(jlong *) result, 0); + break; + + case T_FLOAT: + SET_LOCALS_FLOAT(*(jfloat *) result, 0); + break; + + case T_DOUBLE: + SET_LOCALS_DOUBLE(*(jdouble *) result, 0); + break; + + case T_OBJECT: + case T_ARRAY: + SET_LOCALS_OBJECT(istate->oop_temp(), 0); + break; + + default: + ShouldNotReachHere(); + } + } +} + +void CppInterpreter::accessor_entry(methodOop method, intptr_t UNUSED, TRAPS) +{ + JavaThread *thread = (JavaThread *) THREAD; + ZeroStack *stack = thread->zero_stack(); + intptr_t *locals = stack->sp(); + + // Drop into the slow path if we need a safepoint check + if (SafepointSynchronize::do_call_back()) { + normal_entry(method, 0, THREAD); + return; + } + + // Load the object pointer and drop into the slow path + // if we have a NullPointerException + oop object = LOCALS_OBJECT(0); + if (object == NULL) { + normal_entry(method, 0, THREAD); + return; + } + + // Read the field index from the bytecode, which looks like this: + // 0: aload_0 + // 1: getfield + // 2: index + // 3: index + // 4: ireturn/areturn + // NB this is not raw bytecode: index is in machine order + u1 *code = method->code_base(); + assert(code[0] == Bytecodes::_aload_0 && + code[1] == Bytecodes::_getfield && + (code[4] == Bytecodes::_ireturn || + code[4] == Bytecodes::_areturn), "should do"); + u2 index = Bytes::get_native_u2(&code[2]); + + // Get the entry from the constant pool cache, and drop into + // the slow path if it has not been resolved + constantPoolCacheOop cache = method->constants()->cache(); + ConstantPoolCacheEntry* entry = cache->entry_at(index); + if (!entry->is_resolved(Bytecodes::_getfield)) { + normal_entry(method, 0, THREAD); + return; + } + + // Get the result and push it onto the stack + switch (entry->flag_state()) { + case ltos: + case dtos: + if (stack->available_words() < 1) { + Unimplemented(); + } + stack->alloc(wordSize); + break; + } + if (entry->is_volatile()) { + switch (entry->flag_state()) { + case ctos: + SET_LOCALS_INT(object->char_field_acquire(entry->f2()), 0); + break; + + case btos: + SET_LOCALS_INT(object->byte_field_acquire(entry->f2()), 0); + break; + + case stos: + SET_LOCALS_INT(object->short_field_acquire(entry->f2()), 0); + break; + + case itos: + SET_LOCALS_INT(object->int_field_acquire(entry->f2()), 0); + break; + + case ltos: + SET_LOCALS_LONG(object->long_field_acquire(entry->f2()), 0); + break; + + case ftos: + SET_LOCALS_FLOAT(object->float_field_acquire(entry->f2()), 0); + break; + + case dtos: + SET_LOCALS_DOUBLE(object->double_field_acquire(entry->f2()), 0); + break; + + case atos: + SET_LOCALS_OBJECT(object->obj_field_acquire(entry->f2()), 0); + break; + + default: + ShouldNotReachHere(); + } + } + else { + switch (entry->flag_state()) { + case ctos: + SET_LOCALS_INT(object->char_field(entry->f2()), 0); + break; + + case btos: + SET_LOCALS_INT(object->byte_field(entry->f2()), 0); + break; + + case stos: + SET_LOCALS_INT(object->short_field(entry->f2()), 0); + break; + + case itos: + SET_LOCALS_INT(object->int_field(entry->f2()), 0); + break; + + case ltos: + SET_LOCALS_LONG(object->long_field(entry->f2()), 0); + break; + + case ftos: + SET_LOCALS_FLOAT(object->float_field(entry->f2()), 0); + break; + + case dtos: + SET_LOCALS_DOUBLE(object->double_field(entry->f2()), 0); + break; + + case atos: + SET_LOCALS_OBJECT(object->obj_field(entry->f2()), 0); + break; + + default: + ShouldNotReachHere(); + } + } +} + +void CppInterpreter::empty_entry(methodOop method, intptr_t UNUSED, TRAPS) +{ + JavaThread *thread = (JavaThread *) THREAD; + ZeroStack *stack = thread->zero_stack(); + + // Drop into the slow path if we need a safepoint check + if (SafepointSynchronize::do_call_back()) { + normal_entry(method, 0, THREAD); + return; + } + + // Pop our parameters + stack->set_sp(stack->sp() + method->size_of_parameters()); +} + +bool CppInterpreter::stack_overflow_imminent(JavaThread *thread) +{ + // How is the ABI stack? + address stack_top = thread->stack_base() - thread->stack_size(); + int free_stack = os::current_stack_pointer() - stack_top; + if (free_stack < StackShadowPages * os::vm_page_size()) { + return true; + } + + // How is the Zero stack? + // Throwing a StackOverflowError involves a VM call, which means + // we need a frame on the stack. We should be checking here to + // ensure that methods we call have enough room to install the + // largest possible frame, but that's more than twice the size + // of the entire Zero stack we get by default, so we just check + // we have *some* space instead... + free_stack = thread->zero_stack()->available_words() * wordSize; + if (free_stack < StackShadowPages * os::vm_page_size()) { + return true; + } + + return false; +} + +InterpreterFrame *InterpreterFrame::build(ZeroStack* stack, + const methodOop method, + JavaThread* thread) +{ + int monitor_words = + method->is_synchronized() ? frame::interpreter_frame_monitor_size() : 0; + int stack_words = method->is_native() ? 0 : method->max_stack(); + + if (header_words + monitor_words + stack_words > stack->available_words()) { + Unimplemented(); + } + + intptr_t *locals; + if (method->is_native()) + locals = stack->sp() + (method->size_of_parameters() - 1); + else + locals = stack->sp() + (method->max_locals() - 1); + + stack->push(0); // next_frame, filled in later + intptr_t *fp = stack->sp(); + assert(fp - stack->sp() == next_frame_off, "should be"); + + stack->push(INTERPRETER_FRAME); + assert(fp - stack->sp() == frame_type_off, "should be"); + + interpreterState istate = + (interpreterState) stack->alloc(sizeof(BytecodeInterpreter)); + assert(fp - stack->sp() == istate_off, "should be"); + + istate->set_locals(locals); + istate->set_method(method); + istate->set_self_link(istate); + istate->set_prev_link(NULL); + istate->set_thread(thread); + istate->set_bcp(method->is_native() ? NULL : method->code_base()); + istate->set_constants(method->constants()->cache()); + istate->set_msg(BytecodeInterpreter::method_entry); + istate->set_oop_temp(NULL); + istate->set_mdx(NULL); + istate->set_callee(NULL); + + istate->set_monitor_base((BasicObjectLock *) stack->sp()); + if (method->is_synchronized()) { + BasicObjectLock *monitor = + (BasicObjectLock *) stack->alloc(monitor_words * wordSize); + oop object; + if (method->is_static()) + object = method->constants()->pool_holder()->klass_part()->java_mirror(); + else + object = (oop) locals[0]; + monitor->set_obj(object); + } + + istate->set_stack_base(stack->sp()); + istate->set_stack(stack->sp() - 1); + if (stack_words) + stack->alloc(stack_words * wordSize); + istate->set_stack_limit(stack->sp() - 1); + + return (InterpreterFrame *) fp; +} + +int AbstractInterpreter::BasicType_as_index(BasicType type) +{ + int i = 0; + switch (type) { + case T_BOOLEAN: i = 0; break; + case T_CHAR : i = 1; break; + case T_BYTE : i = 2; break; + case T_SHORT : i = 3; break; + case T_INT : i = 4; break; + case T_LONG : i = 5; break; + case T_VOID : i = 6; break; + case T_FLOAT : i = 7; break; + case T_DOUBLE : i = 8; break; + case T_OBJECT : i = 9; break; + case T_ARRAY : i = 9; break; + default : ShouldNotReachHere(); + } + assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, + "index out of bounds"); + return i; +} + +address InterpreterGenerator::generate_empty_entry() +{ + if (!UseFastEmptyMethods) + return NULL; + + return generate_entry(CppInterpreter::empty_entry); +} + +address InterpreterGenerator::generate_accessor_entry() +{ + if (!UseFastAccessorMethods) + return NULL; + + return generate_entry(CppInterpreter::accessor_entry); +} + +address InterpreterGenerator::generate_native_entry(bool synchronized) +{ + assert (synchronized == false, "should be"); + + return generate_entry(CppInterpreter::native_entry); +} + +address InterpreterGenerator::generate_normal_entry(bool synchronized) +{ + assert (synchronized == false, "should be"); + + return generate_entry(CppInterpreter::normal_entry); +} + +address AbstractInterpreterGenerator::generate_method_entry( + AbstractInterpreter::MethodKind kind) { + + address entry_point = NULL; + + switch (kind) { + case Interpreter::zerolocals: + case Interpreter::zerolocals_synchronized: + break; + + case Interpreter::native: + entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); + break; + + case Interpreter::native_synchronized: + entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); + break; + + case Interpreter::empty: + entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); + break; + + case Interpreter::accessor: + entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); + break; + + case Interpreter::abstract: + entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); + break; + + case Interpreter::method_handle: + entry_point = ((InterpreterGenerator*)this)->generate_method_handle_entry(); + break; + + case Interpreter::java_lang_math_sin: + case Interpreter::java_lang_math_cos: + case Interpreter::java_lang_math_tan: + case Interpreter::java_lang_math_abs: + case Interpreter::java_lang_math_log: + case Interpreter::java_lang_math_log10: + case Interpreter::java_lang_math_sqrt: + entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind); + break; + + default: + ShouldNotReachHere(); + } + + if (entry_point == NULL) + entry_point = ((InterpreterGenerator*)this)->generate_normal_entry(false); + + return entry_point; +} + +InterpreterGenerator::InterpreterGenerator(StubQueue* code) + : CppInterpreterGenerator(code) { + generate_all(); +} + +// Deoptimization helpers + +InterpreterFrame *InterpreterFrame::build(ZeroStack* stack, int size) +{ + int size_in_words = size >> LogBytesPerWord; + assert(size_in_words * wordSize == size, "unaligned"); + assert(size_in_words >= header_words, "too small"); + + if (size_in_words > stack->available_words()) { + Unimplemented(); + } + + stack->push(0); // next_frame, filled in later + intptr_t *fp = stack->sp(); + assert(fp - stack->sp() == next_frame_off, "should be"); + + stack->push(INTERPRETER_FRAME); + assert(fp - stack->sp() == frame_type_off, "should be"); + + interpreterState istate = + (interpreterState) stack->alloc(sizeof(BytecodeInterpreter)); + assert(fp - stack->sp() == istate_off, "should be"); + istate->set_self_link(NULL); // mark invalid + + stack->alloc((size_in_words - header_words) * wordSize); + + return (InterpreterFrame *) fp; +} + +int AbstractInterpreter::layout_activation(methodOop method, + int tempcount, + int popframe_extra_args, + int moncount, + int callee_param_count, + int callee_locals, + frame* caller, + frame* interpreter_frame, + bool is_top_frame) +{ + assert(popframe_extra_args == 0, "what to do?"); + assert(!is_top_frame || (!callee_locals && !callee_param_count), + "top frame should have no caller") + + // This code must exactly match what InterpreterFrame::build + // does (the full InterpreterFrame::build, that is, not the + // one that creates empty frames for the deoptimizer). + // + // If interpreter_frame is not NULL then it will be filled in. + // It's size is determined by a previous call to this method, + // so it should be correct. + // + // Note that tempcount is the current size of the expression + // stack. For top most frames we will allocate a full sized + // expression stack and not the trimmed version that non-top + // frames have. + + int header_words = InterpreterFrame::header_words; + int monitor_words = moncount * frame::interpreter_frame_monitor_size(); + int stack_words = is_top_frame ? method->max_stack() : tempcount; + int callee_extra_locals = callee_locals - callee_param_count; + + if (interpreter_frame) { + intptr_t *locals = interpreter_frame->sp() + method->max_locals(); + interpreterState istate = interpreter_frame->get_interpreterState(); + intptr_t *monitor_base = (intptr_t*) istate; + intptr_t *stack_base = monitor_base - monitor_words; + intptr_t *stack = stack_base - tempcount - 1; + + BytecodeInterpreter::layout_interpreterState(istate, + caller, + NULL, + method, + locals, + stack, + stack_base, + monitor_base, + NULL, + is_top_frame); + } + return header_words + monitor_words + stack_words + callee_extra_locals; +} + +void BytecodeInterpreter::layout_interpreterState(interpreterState istate, + frame* caller, + frame* current, + methodOop method, + intptr_t* locals, + intptr_t* stack, + intptr_t* stack_base, + intptr_t* monitor_base, + intptr_t* frame_bottom, + bool is_top_frame) +{ + istate->set_locals(locals); + istate->set_method(method); + istate->set_self_link(istate); + istate->set_prev_link(NULL); + // thread will be set by a hacky repurposing of frame::patch_pc() + // bcp will be set by vframeArrayElement::unpack_on_stack() + istate->set_constants(method->constants()->cache()); + istate->set_msg(BytecodeInterpreter::method_resume); + istate->set_bcp_advance(0); + istate->set_oop_temp(NULL); + istate->set_mdx(NULL); + if (caller->is_interpreted_frame()) { + interpreterState prev = caller->get_interpreterState(); + prev->set_callee(method); + if (*prev->bcp() == Bytecodes::_invokeinterface) + prev->set_bcp_advance(5); + else + prev->set_bcp_advance(3); + } + istate->set_callee(NULL); + istate->set_monitor_base((BasicObjectLock *) monitor_base); + istate->set_stack_base(stack_base); + istate->set_stack(stack); + istate->set_stack_limit(stack_base - method->max_stack() - 1); +} + +address CppInterpreter::return_entry(TosState state, int length) +{ + Unimplemented(); +} + +address CppInterpreter::deopt_entry(TosState state, int length) +{ + return NULL; +} + +// Helper for (runtime) stack overflow checks + +int AbstractInterpreter::size_top_interpreter_activation(methodOop method) +{ + return 0; +} + +// Helper for figuring out if frames are interpreter frames + +bool CppInterpreter::contains(address pc) +{ +#ifdef PRODUCT + ShouldNotCallThis(); +#else + return false; // make frame::print_value_on work +#endif // !PRODUCT +} + +// Result handlers and convertors + +address CppInterpreterGenerator::generate_result_handler_for( + BasicType type) { + assembler()->advance(1); + return ShouldNotReachHereStub(); +} + +address CppInterpreterGenerator::generate_tosca_to_stack_converter( + BasicType type) { + assembler()->advance(1); + return ShouldNotReachHereStub(); +} + +address CppInterpreterGenerator::generate_stack_to_stack_converter( + BasicType type) { + assembler()->advance(1); + return ShouldNotReachHereStub(); +} + +address CppInterpreterGenerator::generate_stack_to_native_abi_converter( + BasicType type) { + assembler()->advance(1); + return ShouldNotReachHereStub(); +} + +#endif // CC_INTERP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/cppInterpreter_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,44 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + + protected: + // Size of interpreter code + const static int InterpreterCodeSize = 6 * K; + + public: + // Method entries + static void normal_entry(methodOop method, intptr_t UNUSED, TRAPS); + static void native_entry(methodOop method, intptr_t UNUSED, TRAPS); + static void accessor_entry(methodOop method, intptr_t UNUSED, TRAPS); + static void empty_entry(methodOop method, intptr_t UNUSED, TRAPS); + + public: + // Main loop of normal_entry + static void main_loop(int recurse, TRAPS); + + private: + // Stack overflow checks + static bool stack_overflow_imminent(JavaThread *thread);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/debug_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_debug_zero.cpp.incl" + +void pd_ps(frame f) +{ + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/deoptimizerFrame_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,49 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// | ... | +// +--------------------+ ------------------ +// | frame_type | low addresses +// | next_frame | high addresses +// +--------------------+ ------------------ +// | ... | + +class DeoptimizerFrame : public ZeroFrame { + friend class ZeroStackPrinter; + + private: + DeoptimizerFrame() : ZeroFrame() + { + ShouldNotCallThis(); + } + + protected: + enum Layout { + header_words = jf_header_words + }; + + public: + static DeoptimizerFrame *build(ZeroStack* stack); +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/depChecker_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/depChecker_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/disassembler_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,26 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/disassembler_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,35 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// The disassembler prints out zero code annotated +// with Java specific information. + + static int pd_instruction_alignment() { + Unimplemented(); + } + + static const char* pd_cpu_opts() { + Unimplemented(); + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/dump_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,37 @@ +/* + * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_dump_zero.cpp.incl" + +void CompactingPermGenGen::generate_vtable_methods(void** vtbl_list, + void** vtable, + char** md_top, + char* md_end, + char** mc_top, + char* mc_end) +{ + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/entryFrame_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,62 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// | ... | +// +--------------------+ ------------------ +// | parameter n-1 | low addresses +// | ... | +// | parameter 0 | +// | call_wrapper | +// | frame_type | +// | next_frame | high addresses +// +--------------------+ ------------------ +// | ... | + +class EntryFrame : public ZeroFrame { + friend class ZeroStackPrinter; + + private: + EntryFrame() : ZeroFrame() + { + ShouldNotCallThis(); + } + + protected: + enum Layout { + call_wrapper_off = jf_header_words, + header_words + }; + + public: + static EntryFrame *build(ZeroStack* stack, + const intptr_t* parameters, + int parameter_words, + JavaCallWrapper* call_wrapper); + public: + JavaCallWrapper *call_wrapper() const + { + return (JavaCallWrapper *) value_of_word(call_wrapper_off); + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/entry_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,60 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class ZeroEntry { + public: + ZeroEntry() + { + ShouldNotCallThis(); + } + + public: + typedef void (*method_entry_t)(methodOop method, intptr_t base_pc, TRAPS); + + private: + method_entry_t _entry_point; + + public: + method_entry_t entry_point() const + { + return _entry_point; + } + void set_entry_point(method_entry_t entry_point) + { + _entry_point = entry_point; + } + + public: + void invoke(methodOop method, TRAPS) const + { + entry_point()(method, (intptr_t) this, THREAD); + } + + public: + static ByteSize entry_point_offset() + { + return byte_offset_of(ZeroEntry, _entry_point); + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/frame_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,199 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_frame_zero.cpp.incl" + +#ifdef ASSERT +void RegisterMap::check_location_valid() +{ + Unimplemented(); +} +#endif + +bool frame::is_interpreted_frame() const +{ + return zeroframe()->is_interpreter_frame(); +} + +bool frame::is_deoptimizer_frame() const +{ + return zeroframe()->is_deoptimizer_frame(); +} + +frame frame::sender_for_entry_frame(RegisterMap *map) const +{ + assert(map != NULL, "map must be set"); + assert(!entry_frame_is_first(), "next Java fp must be non zero"); + assert(entry_frame_call_wrapper()->anchor()->last_Java_sp() == sender_sp(), + "sender should be next Java frame"); + map->clear(); + assert(map->include_argument_oops(), "should be set by clear"); + return frame(sender_sp()); +} + +frame frame::sender_for_interpreter_frame(RegisterMap *map) const +{ + return frame(sender_sp()); +} + +frame frame::sender_for_compiled_frame(RegisterMap *map) const +{ + return frame(sender_sp()); +} + +frame frame::sender_for_deoptimizer_frame(RegisterMap *map) const +{ + return frame(sender_sp()); +} + +frame frame::sender(RegisterMap* map) const +{ + // Default is not to follow arguments; the various + // sender_for_xxx methods update this accordingly. + map->set_include_argument_oops(false); + + if (is_entry_frame()) + return sender_for_entry_frame(map); + + if (is_interpreted_frame()) + return sender_for_interpreter_frame(map); + + assert(_cb == CodeCache::find_blob(pc()),"Must be the same"); + if (_cb != NULL) { + return sender_for_compiled_frame(map); + } + + if (is_deoptimizer_frame()) + return sender_for_deoptimizer_frame(map); + + Unimplemented(); +} + +#ifdef CC_INTERP +BasicObjectLock* frame::interpreter_frame_monitor_begin() const +{ + return get_interpreterState()->monitor_base(); +} + +BasicObjectLock* frame::interpreter_frame_monitor_end() const +{ + return (BasicObjectLock*) get_interpreterState()->stack_base(); +} +#endif // CC_INTERP + +void frame::patch_pc(Thread* thread, address pc) +{ + // We borrow this call to set the thread pointer in the interpreter + // state; the hook to set up deoptimized frames isn't supplied it. + assert(pc == NULL, "should be"); + get_interpreterState()->set_thread((JavaThread *) thread); +} + +bool frame::safe_for_sender(JavaThread *thread) +{ + Unimplemented(); +} + +void frame::pd_gc_epilog() +{ +} + +bool frame::is_interpreted_frame_valid(JavaThread *thread) const +{ + Unimplemented(); +} + +BasicType frame::interpreter_frame_result(oop* oop_result, + jvalue* value_result) +{ + assert(is_interpreted_frame(), "interpreted frame expected"); + methodOop method = interpreter_frame_method(); + BasicType type = method->result_type(); + intptr_t* tos_addr = (intptr_t *) interpreter_frame_tos_address(); + oop obj; + + switch (type) { + case T_VOID: + break; + case T_BOOLEAN: + value_result->z = *(jboolean *) tos_addr; + break; + case T_BYTE: + value_result->b = *(jbyte *) tos_addr; + break; + case T_CHAR: + value_result->c = *(jchar *) tos_addr; + break; + case T_SHORT: + value_result->s = *(jshort *) tos_addr; + break; + case T_INT: + value_result->i = *(jint *) tos_addr; + break; + case T_LONG: + value_result->j = *(jlong *) tos_addr; + break; + case T_FLOAT: + value_result->f = *(jfloat *) tos_addr; + break; + case T_DOUBLE: + value_result->d = *(jdouble *) tos_addr; + break; + + case T_OBJECT: + case T_ARRAY: + if (method->is_native()) { + obj = get_interpreterState()->oop_temp(); + } + else { + oop* obj_p = (oop *) tos_addr; + obj = (obj_p == NULL) ? (oop) NULL : *obj_p; + } + assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check"); + *oop_result = obj; + break; + + default: + ShouldNotReachHere(); + } + + return type; +} + +int frame::frame_size(RegisterMap* map) const +{ +#ifdef PRODUCT + ShouldNotCallThis(); +#else + return 0; // make javaVFrame::print_value work +#endif // PRODUCT +} + +intptr_t* frame::interpreter_frame_tos_at(jint offset) const +{ + int index = (Interpreter::expr_offset_in_bytes(offset) / wordSize); + return &interpreter_frame_tos_address()[index]; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/frame_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,74 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + // A frame represents a physical stack frame (an activation). Frames + // can be C or Java frames, and the Java frames can be interpreted or + // compiled. In contrast, vframes represent source-level activations, + // so that one physical frame can correspond to multiple source level + // frames because of inlining. A frame is comprised of {pc, sp} + + public: + enum { + pc_return_offset = 0 + }; + + public: + // Constructors + frame(intptr_t* sp); + + // accessors for the instance variables + intptr_t* fp() const + { + return (intptr_t *) -1; + } + +#ifdef CC_INTERP + inline interpreterState get_interpreterState() const; +#endif // CC_INTERP + + public: + const ZeroFrame *zeroframe() const + { + return (ZeroFrame *) sp(); + } + + const EntryFrame *zero_entryframe() const + { + return zeroframe()->as_entry_frame(); + } + const InterpreterFrame *zero_interpreterframe() const + { + return zeroframe()->as_interpreter_frame(); + } + const SharkFrame *zero_sharkframe() const + { + return zeroframe()->as_shark_frame(); + } + + public: + bool is_deoptimizer_frame() const; + + public: + frame sender_for_deoptimizer_frame(RegisterMap* map) const;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/frame_zero.inline.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,175 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include <entryFrame_zero.hpp> +#include <interpreterFrame_zero.hpp> +#include <sharkFrame_zero.hpp> +#include <deoptimizerFrame_zero.hpp> + +// Constructors + +inline frame::frame() +{ + _sp = NULL; + _pc = NULL; + _cb = NULL; + _deopt_state = unknown; +} + +inline frame::frame(intptr_t* sp) +{ + _sp = sp; + switch (zeroframe()->type()) { + case ZeroFrame::ENTRY_FRAME: + _pc = StubRoutines::call_stub_return_pc(); + _cb = NULL; + break; + + case ZeroFrame::INTERPRETER_FRAME: + _pc = NULL; + _cb = NULL; + break; + + case ZeroFrame::SHARK_FRAME: + _pc = zero_sharkframe()->pc(); + _cb = CodeCache::find_blob(pc()); + break; + + case ZeroFrame::DEOPTIMIZER_FRAME: + _pc = NULL; + _cb = NULL; + break; + + default: + ShouldNotReachHere(); + } + _deopt_state = not_deoptimized; +} + +// Accessors + +inline intptr_t* frame::sender_sp() const +{ + return (intptr_t *) zeroframe()->next(); +} + +inline intptr_t* frame::link() const +{ + Unimplemented(); +} + +#ifdef CC_INTERP +inline interpreterState frame::get_interpreterState() const +{ + return zero_interpreterframe()->interpreter_state(); +} + +inline intptr_t** frame::interpreter_frame_locals_addr() const +{ + return &(get_interpreterState()->_locals); +} + +inline intptr_t* frame::interpreter_frame_bcx_addr() const +{ + return (intptr_t*) &(get_interpreterState()->_bcp); +} + +inline constantPoolCacheOop* frame::interpreter_frame_cache_addr() const +{ + return &(get_interpreterState()->_constants); +} + +inline methodOop* frame::interpreter_frame_method_addr() const +{ + return &(get_interpreterState()->_method); +} + +inline intptr_t* frame::interpreter_frame_mdx_addr() const +{ + return (intptr_t*) &(get_interpreterState()->_mdx); +} + +inline intptr_t* frame::interpreter_frame_tos_address() const +{ + return get_interpreterState()->_stack + 1; +} +#endif // CC_INTERP + +inline int frame::interpreter_frame_monitor_size() +{ + return BasicObjectLock::size(); +} + +inline intptr_t* frame::interpreter_frame_expression_stack() const +{ + intptr_t* monitor_end = (intptr_t*) interpreter_frame_monitor_end(); + return monitor_end - 1; +} + +inline jint frame::interpreter_frame_expression_stack_direction() +{ + return -1; +} + +// Return a unique id for this frame. The id must have a value where +// we can distinguish identity and younger/older relationship. NULL +// represents an invalid (incomparable) frame. +inline intptr_t* frame::id() const +{ + return sp(); +} + +inline JavaCallWrapper* frame::entry_frame_call_wrapper() const +{ + return zero_entryframe()->call_wrapper(); +} + +inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) +{ + Unimplemented(); +} + +inline oop frame::saved_oop_result(RegisterMap* map) const +{ + Unimplemented(); +} + +inline bool frame::is_older(intptr_t* id) const +{ + Unimplemented(); +} + +inline intptr_t* frame::entry_frame_argument_at(int offset) const +{ + Unimplemented(); +} + +inline intptr_t* frame::unextended_sp() const +{ + if (zeroframe()->is_shark_frame()) + return zero_sharkframe()->unextended_sp(); + else + return (intptr_t *) -1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/globalDefinitions_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/globals_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,55 @@ +/* + * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// +// Set the default values for platform dependent flags used by the +// runtime system. See globals.hpp for details of what they do. +// + +define_pd_global(bool, ConvertSleepToYield, true); +define_pd_global(bool, ShareVtableStubs, true); +define_pd_global(bool, CountInterpCalls, true); +define_pd_global(bool, NeedsDeoptSuspend, false); + +define_pd_global(bool, ImplicitNullChecks, true); +define_pd_global(bool, UncommonNullCast, true); + +define_pd_global(intx, CodeEntryAlignment, 32); +define_pd_global(uintx, TLABSize, 0); +#ifdef _LP64 +define_pd_global(uintx, NewSize, ScaleForWordSize(2048 * K)); +#else +define_pd_global(uintx, NewSize, ScaleForWordSize(1024 * K)); +#endif // _LP64 +define_pd_global(intx, InlineFrequencyCount, 100); +define_pd_global(intx, InlineSmallCode, 1000); +define_pd_global(intx, PreInflateSpin, 10); + +define_pd_global(intx, StackYellowPages, 2); +define_pd_global(intx, StackRedPages, 1); +define_pd_global(intx, StackShadowPages, 3 LP64_ONLY(+3) DEBUG_ONLY(+3)); + +define_pd_global(bool, RewriteBytecodes, true); +define_pd_global(bool, RewriteFrequentPairs, true);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/icBuffer_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,52 @@ +/* + * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_icBuffer_zero.cpp.incl" + +int InlineCacheBuffer::ic_stub_code_size() +{ + // NB set this once the functions below are implemented + return 4; +} + +void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin, + oop cached_oop, + address entry_point) { + // NB ic_stub_code_size() must return the size of the code we generate + Unimplemented(); +} + +address InlineCacheBuffer::ic_buffer_entry_point(address code_begin) +{ + // NB ic_stub_code_size() must return the size of the code we generate + Unimplemented(); +} + +oop InlineCacheBuffer::ic_buffer_cached_oop(address code_begin) +{ + // NB ic_stub_code_size() must return the size of the code we generate + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/icache_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,36 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_icache_zero.cpp.incl" + + +void ICacheStubGenerator::generate_icache_flush( + ICache::flush_icache_stub_t* flush_icache_stub) { + + StubCodeMark mark(this, "ICache", "flush_icache_stub"); + + *flush_icache_stub = (ICache::flush_icache_stub_t)UnimplementedStub(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/icache_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,33 @@ +/* + * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Interface for updating the instruction cache. Whenever the VM +// modifies code, part of the processor instruction cache potentially +// has to be flushed. + +class ICache : public AbstractICache { + + // Use default implementation +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/interp_masm_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/interp_masm_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,34 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file specializes the assember with interpreter-specific macros + +class InterpreterMacroAssembler : public MacroAssembler { + public: + InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {} + RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, Register tmp, int offset) { + Unimplemented(); + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/interpreterFrame_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,71 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#ifdef CC_INTERP +// | ... | +// +--------------------+ ------------------ +// | stack slot n-1 | low addresses +// | ... | +// | stack slot 0 | +// | monitor 0 (maybe) | +// | ... | +// | interpreter state | +// | ... | +// | frame_type | +// | next_frame | high addresses +// +--------------------+ ------------------ +// | ... | + +class InterpreterFrame : public ZeroFrame { + friend class ZeroStackPrinter; + friend class AbstractInterpreter; + + private: + InterpreterFrame() : ZeroFrame() + { + ShouldNotCallThis(); + } + + protected: + enum Layout { + istate_off = jf_header_words + + (align_size_up_(sizeof(BytecodeInterpreter), + wordSize) >> LogBytesPerWord) - 1, + header_words + }; + + public: + static InterpreterFrame *build(ZeroStack* stack, + const methodOop method, + JavaThread* thread); + static InterpreterFrame *build(ZeroStack* stack, int size); + + public: + interpreterState interpreter_state() const + { + return (interpreterState) addr_of_word(istate_off); + } +}; +#endif // CC_INTERP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/interpreterGenerator_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,38 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + + // Generation of Interpreter + // + friend class AbstractInterpreterGenerator; + + private: + address generate_normal_entry(bool synchronized); + address generate_native_entry(bool synchronized); + address generate_abstract_entry(); + address generate_math_entry(AbstractInterpreter::MethodKind kind); + address generate_empty_entry(); + address generate_accessor_entry(); + address generate_method_handle_entry();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/interpreterRT_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,170 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_interpreterRT_zero.cpp.incl" + +void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_int() +{ + push(T_INT); + _cif->nargs++; +} + +void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_long() +{ + push(T_LONG); + _cif->nargs++; +} + +void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_float() +{ + push(T_FLOAT); + _cif->nargs++; +} + +void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_double() +{ + push(T_DOUBLE); + _cif->nargs++; +} + +void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_object() +{ + push(T_OBJECT); + _cif->nargs++; +} + +void InterpreterRuntime::SignatureHandlerGeneratorBase::push(BasicType type) +{ + ffi_type *ftype; + switch (type) { + case T_VOID: + ftype = &ffi_type_void; + break; + + case T_BOOLEAN: + ftype = &ffi_type_uint8; + break; + + case T_CHAR: + ftype = &ffi_type_uint16; + break; + + case T_BYTE: + ftype = &ffi_type_sint8; + break; + + case T_SHORT: + ftype = &ffi_type_sint16; + break; + + case T_INT: + ftype = &ffi_type_sint32; + break; + + case T_LONG: + ftype = &ffi_type_sint64; + break; + + case T_FLOAT: + ftype = &ffi_type_float; + break; + + case T_DOUBLE: + ftype = &ffi_type_double; + break; + + case T_OBJECT: + case T_ARRAY: + ftype = &ffi_type_pointer; + break; + + default: + ShouldNotReachHere(); + } + push((intptr_t) ftype); +} + +// For fast signature handlers the "signature handler" is generated +// into a temporary buffer. It is then copied to its final location, +// and pd_set_handler is called on it. We have this two stage thing +// to accomodate this. + +void InterpreterRuntime::SignatureHandlerGeneratorBase::generate( + uint64_t fingerprint) { + + // Build the argument types list + pass_object(); + if (method()->is_static()) + pass_object(); + iterate(fingerprint); + + // Tack on the result type + push(method()->result_type()); +} + +void InterpreterRuntime::SignatureHandler::finalize() +{ + ffi_status status = + ffi_prep_cif(cif(), + FFI_DEFAULT_ABI, + argument_count(), + result_type(), + argument_types()); + + assert(status == FFI_OK, "should be"); +} + +IRT_ENTRY(address, + InterpreterRuntime::slow_signature_handler(JavaThread* thread, + methodOop method, + intptr_t* unused1, + intptr_t* unused2)) + ZeroStack *stack = thread->zero_stack(); + + int required_words = + (align_size_up(sizeof(ffi_cif), wordSize) >> LogBytesPerWord) + + (method->is_static() ? 2 : 1) + method->size_of_parameters() + 1; + if (required_words > stack->available_words()) { + Unimplemented(); + } + + intptr_t *buf = (intptr_t *) stack->alloc(required_words * wordSize); + SlowSignatureHandlerGenerator sshg(methodHandle(thread, method), buf); + sshg.generate(UCONST64(-1)); + + SignatureHandler *handler = sshg.handler(); + handler->finalize(); + + return (address) handler; +IRT_END + +void SignatureHandlerLibrary::pd_set_handler(address handlerAddr) +{ + InterpreterRuntime::SignatureHandler *handler = + InterpreterRuntime::SignatureHandler::from_handlerAddr(handlerAddr); + + handler->finalize(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/interpreterRT_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,144 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class SignatureHandler +{ + public: + static SignatureHandler *from_handlerAddr(address handlerAddr) + { + return (SignatureHandler *) handlerAddr; + } + + public: + ffi_cif* cif() const + { + return (ffi_cif *) this; + } + + int argument_count() const + { + return cif()->nargs; + } + + ffi_type** argument_types() const + { + return (ffi_type**) (cif() + 1); + } + + ffi_type* argument_type(int i) const + { + return argument_types()[i]; + } + + ffi_type* result_type() const + { + return *(argument_types() + argument_count()); + } + + protected: + friend class InterpreterRuntime; + friend class SignatureHandlerLibrary; + + void finalize(); +}; + +class SignatureHandlerGeneratorBase : public NativeSignatureIterator +{ + private: + ffi_cif* _cif; + + protected: + SignatureHandlerGeneratorBase(methodHandle method, ffi_cif *cif) + : NativeSignatureIterator(method), _cif(cif) + { + _cif->nargs = 0; + } + + ffi_cif *cif() const + { + return _cif; + } + + public: + void generate(uint64_t fingerprint); + + private: + void pass_int(); + void pass_long(); + void pass_float(); + void pass_double(); + void pass_object(); + + private: + void push(BasicType type); + virtual void push(intptr_t value) = 0; +}; + +class SignatureHandlerGenerator : public SignatureHandlerGeneratorBase +{ + private: + CodeBuffer* _cb; + + public: + SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) + : SignatureHandlerGeneratorBase(method, (ffi_cif *) buffer->code_end()), + _cb(buffer) + { + _cb->set_code_end((address) (cif() + 1)); + } + + private: + void push(intptr_t value) + { + intptr_t *dst = (intptr_t *) _cb->code_end(); + _cb->set_code_end((address) (dst + 1)); + *dst = value; + } +}; + +class SlowSignatureHandlerGenerator : public SignatureHandlerGeneratorBase +{ + private: + intptr_t *_dst; + + public: + SlowSignatureHandlerGenerator(methodHandle method, intptr_t* buf) + : SignatureHandlerGeneratorBase(method, (ffi_cif *) buf) + { + _dst = (intptr_t *) (cif() + 1); + } + + private: + void push(intptr_t value) + { + *(_dst++) = value; + } + + public: + SignatureHandler *handler() const + { + return (SignatureHandler *) cif(); + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/interpreter_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,76 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_interpreter_zero.cpp.incl" + +address AbstractInterpreterGenerator::generate_slow_signature_handler() +{ + _masm->advance(1); + return (address) InterpreterRuntime::slow_signature_handler; +} + +address InterpreterGenerator::generate_math_entry( + AbstractInterpreter::MethodKind kind) +{ + if (!InlineIntrinsics) + return NULL; + + Unimplemented(); +} + +address InterpreterGenerator::generate_abstract_entry() +{ + return UnimplementedEntry(); +} + +address InterpreterGenerator::generate_method_handle_entry() +{ + return UnimplementedEntry(); +} + +int AbstractInterpreter::size_activation(methodOop method, + int tempcount, + int popframe_extra_args, + int moncount, + int callee_param_count, + int callee_locals, + bool is_top_frame) +{ + return layout_activation(method, + tempcount, + popframe_extra_args, + moncount, + callee_param_count, + callee_locals, + (frame*) NULL, + (frame*) NULL, + is_top_frame); +} + +void Deoptimization::unwind_callee_save_values(frame* f, + vframeArray* vframe_array) +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/interpreter_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,62 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + public: + static void invoke_method(methodOop method, address entry_point, TRAPS) + { + ((ZeroEntry *) entry_point)->invoke(method, THREAD); + } + + public: + static int expr_index_at(int i) + { + return stackElementWords() * i; + } + static int expr_tag_index_at(int i) + { + assert(TaggedStackInterpreter, "should not call this"); + Unimplemented(); + } + + static int expr_offset_in_bytes(int i) + { + return stackElementSize() * i; + } + static int expr_tag_offset_in_bytes(int i) + { + assert(TaggedStackInterpreter, "should not call this"); + Unimplemented(); + } + + static int local_index_at(int i) + { + assert(i <= 0, "local direction already negated"); + return stackElementWords() * i + (value_offset_in_bytes() / wordSize); + } + static int local_tag_index_at(int i) + { + assert(TaggedStackInterpreter, "should not call this"); + Unimplemented(); + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/javaFrameAnchor_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,78 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +public: + // Each arch must define reset, save, restore + // These are used by objects that only care about: + // 1 - initializing a new state (thread creation, javaCalls) + // 2 - saving a current state (javaCalls) + // 3 - restoring an old state (javaCalls) + + void clear() + { + // clearing _last_Java_sp must be first + _last_Java_sp = NULL; + // fence? + _last_Java_pc = NULL; + } + + void copy(JavaFrameAnchor* src) + { + // In order to make sure the transition state is valid for "this" + // We must clear _last_Java_sp before copying the rest of the new + // data + // + // Hack Alert: Temporary bugfix for 4717480/4721647 To act like + // previous version (pd_cache_state) don't NULL _last_Java_sp + // unless the value is changing + // + if (_last_Java_sp != src->_last_Java_sp) + _last_Java_sp = NULL; + + _last_Java_pc = src->_last_Java_pc; + // Must be last so profiler will always see valid frame if + // has_last_frame() is true + _last_Java_sp = src->_last_Java_sp; + } + + bool walkable() + { + return true; + } + + void make_walkable(JavaThread* thread) + { + // nothing to do + } + + intptr_t* last_Java_sp() const + { + return _last_Java_sp; + } + + void set_last_Java_sp(intptr_t* sp) + { + _last_Java_sp = sp; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/jniFastGetField_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,67 @@ +/* + * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_jniFastGetField_zero.cpp.incl" + +address JNI_FastGetField::generate_fast_get_boolean_field() +{ + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_byte_field() +{ + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_char_field() +{ + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_short_field() +{ + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_int_field() +{ + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_long_field() +{ + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_float_field() +{ + return (address) -1; +} + +address JNI_FastGetField::generate_fast_get_double_field() +{ + return (address) -1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/jniTypes_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,108 @@ +/* + * Copyright 1998-2002 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file holds platform-dependent routines used to write primitive jni +// types to the array of arguments passed into JavaCalls::call + +class JNITypes : AllStatic { + // These functions write a java primitive type (in native format) + // to a java stack slot array to be passed as an argument to JavaCalls:calls. + // I.e., they are functionally 'push' operations if they have a 'pos' + // formal parameter. Note that jlong's and jdouble's are written + // _in reverse_ of the order in which they appear in the interpreter + // stack. This is because call stubs (see stubGenerator_zero.cpp) + // reverse the argument list constructed by JavaCallArguments (see + // javaCalls.hpp). + +private: + // Helper routines. + static inline void put_int2 (jint *from, jint *to) { to[0] = from[0]; to[1] = from[1]; } + static inline void put_int2 (jint *from, jint *to, int& pos) { put_int2 (from, (jint *)((intptr_t *)to + pos)); pos += 2; } + static inline void put_int2r(jint *from, jint *to) { to[0] = from[1]; to[1] = from[0]; } + static inline void put_int2r(jint *from, jint *to, int& pos) { put_int2r(from, (jint *)((intptr_t *)to + pos)); pos += 2; } + +public: + // Ints are stored in native format in one JavaCallArgument slot at *to. + static inline void put_int(jint from, intptr_t *to) { *(jint *)(to + 0 ) = from; } + static inline void put_int(jint from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = from; } + static inline void put_int(jint *from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = *from; } + +#ifdef _LP64 + // Longs are stored in native format in one JavaCallArgument slot at *(to+1). + static inline void put_long(jlong from, intptr_t *to) { *(jlong *)(to + 1 + 0) = from; } + static inline void put_long(jlong from, intptr_t *to, int& pos) { *(jlong *)(to + 1 + pos) = from; pos += 2; } + static inline void put_long(jlong *from, intptr_t *to, int& pos) { *(jlong *)(to + 1 + pos) = *from; pos += 2; } +#else + // Longs are stored in reversed native word format in two JavaCallArgument slots at *to. + // The high half is in *(to+1) and the low half in *to. + static inline void put_long(jlong from, intptr_t *to) { put_int2r((jint *)&from, (jint *)to); } + static inline void put_long(jlong from, intptr_t *to, int& pos) { put_int2r((jint *)&from, (jint *)to, pos); } + static inline void put_long(jlong *from, intptr_t *to, int& pos) { put_int2r((jint *) from, (jint *)to, pos); } +#endif + + // Oops are stored in native format in one JavaCallArgument slot at *to. + static inline void put_obj(oop from, intptr_t *to) { *(oop *)(to + 0 ) = from; } + static inline void put_obj(oop from, intptr_t *to, int& pos) { *(oop *)(to + pos++) = from; } + static inline void put_obj(oop *from, intptr_t *to, int& pos) { *(oop *)(to + pos++) = *from; } + + // Floats are stored in native format in one JavaCallArgument slot at *to. + static inline void put_float(jfloat from, intptr_t *to) { *(jfloat *)(to + 0 ) = from; } + static inline void put_float(jfloat from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = from; } + static inline void put_float(jfloat *from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = *from; } + +#ifdef _LP64 + // Doubles are stored in native word format in one JavaCallArgument slot at *(to+1). + static inline void put_double(jdouble from, intptr_t *to) { *(jdouble *)(to + 1 + 0) = from; } + static inline void put_double(jdouble from, intptr_t *to, int& pos) { *(jdouble *)(to + 1 + pos) = from; pos += 2; } + static inline void put_double(jdouble *from, intptr_t *to, int& pos) { *(jdouble *)(to + 1 + pos) = *from; pos += 2; } +#else + // Doubles are stored in reversed native word format in two JavaCallArgument slots at *to. + static inline void put_double(jdouble from, intptr_t *to) { put_int2r((jint *)&from, (jint *)to); } + static inline void put_double(jdouble from, intptr_t *to, int& pos) { put_int2r((jint *)&from, (jint *)to, pos); } + static inline void put_double(jdouble *from, intptr_t *to, int& pos) { put_int2r((jint *) from, (jint *)to, pos); } +#endif + + // The get_xxx routines, on the other hand, actually _do_ fetch + // java primitive types from the interpreter stack. + static inline jint get_int(intptr_t *from) { return *(jint *)from; } + +#ifdef _LP64 + static inline jlong get_long(intptr_t *from) { return *(jlong *)from; } +#else + static inline jlong get_long(intptr_t *from) { return ((jlong)(*( signed int *)((jint *)from )) << 32) | + ((jlong)(*(unsigned int *)((jint *)from + 1)) << 0); } +#endif + + static inline oop get_obj(intptr_t *from) { return *(oop *)from; } + static inline jfloat get_float(intptr_t *from) { return *(jfloat *)from; } + +#ifdef _LP64 + static inline jdouble get_double(intptr_t *from) { return *(jdouble *)from; } +#else + static inline jdouble get_double(intptr_t *from) { jlong jl = ((jlong)(*( signed int *)((jint *)from )) << 32) | + ((jlong)(*(unsigned int *)((jint *)from + 1)) << 0); + return *(jdouble *)&jl; } +#endif + +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/jni_zero.h Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,37 @@ +/* + * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +#define JNIEXPORT +#define JNIIMPORT +#define JNICALL + +typedef int jint; +typedef signed char jbyte; + +#ifdef _LP64 +typedef long jlong; +#else +typedef long long jlong; +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/methodHandles_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,27 @@ +/* + * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_methodHandles_zero.cpp.incl"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/nativeInst_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,50 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_nativeInst_zero.cpp.incl" + +// This method is called by nmethod::make_not_entrant_or_zombie to +// insert a jump to SharedRuntime::get_handle_wrong_method_stub() +// (dest) at the start of a compiled method (verified_entry) to avoid +// a race where a method is invoked while being made non-entrant. +// +// In Shark, verified_entry is a pointer to a SharkEntry. We can +// handle this simply by changing it's entry point to point at the +// interpreter. This only works because the interpreter and Shark +// calling conventions are the same. + +void NativeJump::patch_verified_entry(address entry, + address verified_entry, + address dest) +{ + assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "should be"); + +#ifdef CC_INTERP + ((ZeroEntry*) verified_entry)->set_entry_point(CppInterpreter::normal_entry); +#else + Unimplemented(); +#endif // CC_INTERP +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/nativeInst_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,220 @@ +/* + * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// We have interfaces for the following instructions: +// - NativeInstruction +// - - NativeCall +// - - NativeMovConstReg +// - - NativeMovConstRegPatching +// - - NativeJump +// - - NativeIllegalOpCode +// - - NativeReturn +// - - NativeReturnX (return with argument) +// - - NativePushConst +// - - NativeTstRegMem + +// The base class for different kinds of native instruction abstractions. +// Provides the primitive operations to manipulate code relative to this. + +class NativeInstruction VALUE_OBJ_CLASS_SPEC +{ + public: + bool is_jump() + { + Unimplemented(); + } + + bool is_safepoint_poll() + { + Unimplemented(); + } +}; + +inline NativeInstruction* nativeInstruction_at(address address) +{ + Unimplemented(); +} + +class NativeCall : public NativeInstruction +{ + public: + enum zero_specific_constants { + instruction_size = 0 // not used within the interpreter + }; + + address instruction_address() const + { + Unimplemented(); + } + + address next_instruction_address() const + { + Unimplemented(); + } + + address return_address() const + { + Unimplemented(); + } + + address destination() const + { + Unimplemented(); + } + + void set_destination_mt_safe(address dest) + { + Unimplemented(); + } + + void verify_alignment() + { + Unimplemented(); + } + + void verify() + { + Unimplemented(); + } + + static bool is_call_before(address return_address) + { + Unimplemented(); + } +}; + +inline NativeCall* nativeCall_before(address return_address) +{ + Unimplemented(); +} + +inline NativeCall* nativeCall_at(address address) +{ + Unimplemented(); +} + +class NativeMovConstReg : public NativeInstruction +{ + public: + address next_instruction_address() const + { + Unimplemented(); + } + + intptr_t data() const + { + Unimplemented(); + } + + void set_data(intptr_t x) + { + Unimplemented(); + } +}; + +inline NativeMovConstReg* nativeMovConstReg_at(address address) +{ + Unimplemented(); +} + +class NativeMovRegMem : public NativeInstruction +{ + public: + int offset() const + { + Unimplemented(); + } + + void set_offset(intptr_t x) + { + Unimplemented(); + } + + void add_offset_in_bytes(int add_offset) + { + Unimplemented(); + } +}; + +inline NativeMovRegMem* nativeMovRegMem_at(address address) +{ + Unimplemented(); +} + +class NativeJump : public NativeInstruction +{ + public: + enum zero_specific_constants { + instruction_size = 0 // not used within the interpreter + }; + + address jump_destination() const + { + Unimplemented(); + } + + void set_jump_destination(address dest) + { + Unimplemented(); + } + + static void check_verified_entry_alignment(address entry, + address verified_entry) + { + } + + static void patch_verified_entry(address entry, + address verified_entry, + address dest); +}; + +inline NativeJump* nativeJump_at(address address) +{ + Unimplemented(); +} + +class NativeGeneralJump : public NativeInstruction +{ + public: + address jump_destination() const + { + Unimplemented(); + } + + static void insert_unconditional(address code_pos, address entry) + { + Unimplemented(); + } + + static void replace_mt_safe(address instr_addr, address code_buffer) + { + Unimplemented(); + } +}; + +inline NativeGeneralJump* nativeGeneralJump_at(address address) +{ + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/registerMap_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,39 @@ +/* + * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + // machine-dependent implemention for register maps + friend class frame; + + private: + // This is the hook for finding a register in an "well-known" location, + // such as a register block of a predetermined format. + // Since there is none, we just return NULL. + // See registerMap_sparc.hpp for an example of grabbing registers + // from register save areas of a standard layout. + address pd_location(VMReg reg) const {return NULL;} + + // no PD state to clear or copy: + void pd_clear() {} + void pd_initialize() {} + void pd_initialize_from(const RegisterMap* map) {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/register_definitions_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/register_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_register_zero.cpp.incl" + +const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers; +const int ConcreteRegisterImpl::max_fpr = + ConcreteRegisterImpl::max_gpr + FloatRegisterImpl::number_of_registers; + +const char* RegisterImpl::name() const { + Unimplemented(); +} + +const char* FloatRegisterImpl::name() const { + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/register_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,116 @@ +/* + * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class VMRegImpl; +typedef VMRegImpl* VMReg; + +// Use Register as shortcut +class RegisterImpl; +typedef RegisterImpl* Register; + +inline Register as_Register(int encoding) { + return (Register)(intptr_t) encoding; +} + +// The implementation of integer registers for the zero architecture +class RegisterImpl : public AbstractRegisterImpl { + public: + enum { + number_of_registers = 0 + }; + + // construction + inline friend Register as_Register(int encoding); + VMReg as_VMReg(); + + // derived registers, offsets, and addresses + Register successor() const + { + return as_Register(encoding() + 1); + } + + // accessors + int encoding() const + { + assert(is_valid(), "invalid register"); + return (intptr_t)this; + } + bool is_valid() const + { + return 0 <= (intptr_t) this && (intptr_t)this < number_of_registers; + } + const char* name() const; +}; + +// Use FloatRegister as shortcut +class FloatRegisterImpl; +typedef FloatRegisterImpl* FloatRegister; + +inline FloatRegister as_FloatRegister(int encoding) { + return (FloatRegister)(intptr_t) encoding; +} + +// The implementation of floating point registers for the zero architecture +class FloatRegisterImpl : public AbstractRegisterImpl { + public: + enum { + number_of_registers = 0 + }; + + // construction + inline friend FloatRegister as_FloatRegister(int encoding); + VMReg as_VMReg(); + + // derived registers, offsets, and addresses + FloatRegister successor() const + { + return as_FloatRegister(encoding() + 1); + } + + // accessors + int encoding() const + { + assert(is_valid(), "invalid register"); + return (intptr_t)this; + } + bool is_valid() const + { + return 0 <= (intptr_t) this && (intptr_t)this < number_of_registers; + } + const char* name() const; +}; + +class ConcreteRegisterImpl : public AbstractRegisterImpl { + public: + enum { + number_of_registers = RegisterImpl::number_of_registers + + FloatRegisterImpl::number_of_registers + }; + + static const int max_gpr; + static const int max_fpr; +}; + +CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/relocInfo_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,77 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_relocInfo_zero.cpp.incl" + +void Relocation::pd_set_data_value(address x, intptr_t o) +{ + Unimplemented(); +} + +address Relocation::pd_call_destination(address orig_addr) +{ + Unimplemented(); +} + +void Relocation::pd_set_call_destination(address x) +{ + Unimplemented(); +} + +address Relocation::pd_get_address_from_code() +{ + Unimplemented(); +} + +address* Relocation::pd_address_in_code() +{ + // Relocations in Shark are just stored directly + return (address *) addr(); +} + +int Relocation::pd_breakpoint_size() +{ + Unimplemented(); +} + +void Relocation::pd_swap_in_breakpoint(address x, short* instrs, + int instrlen) +{ + Unimplemented(); +} + +void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) +{ + Unimplemented(); +} + +void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer *dest) { + Unimplemented(); +} + +void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/relocInfo_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,33 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + // machine-dependent parts of class relocInfo + private: + enum + { + // these constants mean nothing without an assembler + offset_unit = 1, + format_width = 1 + };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/sharedRuntime_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,116 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_sharedRuntime_zero.cpp.incl" + +DeoptimizationBlob *SharedRuntime::_deopt_blob; +SafepointBlob *SharedRuntime::_polling_page_safepoint_handler_blob; +SafepointBlob *SharedRuntime::_polling_page_return_handler_blob; +RuntimeStub *SharedRuntime::_wrong_method_blob; +RuntimeStub *SharedRuntime::_ic_miss_blob; +RuntimeStub *SharedRuntime::_resolve_opt_virtual_call_blob; +RuntimeStub *SharedRuntime::_resolve_virtual_call_blob; +RuntimeStub *SharedRuntime::_resolve_static_call_blob; + +int SharedRuntime::java_calling_convention(const BasicType *sig_bt, + VMRegPair *regs, + int total_args_passed, + int is_outgoing) +{ + return 0; +} + +AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters( + MacroAssembler *masm, + int total_args_passed, + int comp_args_on_stack, + const BasicType *sig_bt, + const VMRegPair *regs) +{ + address i2c_entry = UnimplementedStub(); + address c2i_entry = UnimplementedStub(); + address c2i_unverified_entry = UnimplementedStub(); + return new AdapterHandlerEntry(i2c_entry, c2i_entry, c2i_unverified_entry); +} + +nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, + methodHandle method, + int total_in_args, + int comp_args_on_stack, + BasicType *in_sig_bt, + VMRegPair *in_regs, + BasicType ret_type) +{ + Unimplemented(); +} + +int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) +{ + return 0; +} + +uint SharedRuntime::out_preserve_stack_slots() +{ + Unimplemented(); +} + +static RuntimeStub* generate_empty_runtime_stub(const char* name) +{ + CodeBuffer buffer(name, 0, 0); + return RuntimeStub::new_runtime_stub(name, &buffer, 0, 0, NULL, false); +} + +static SafepointBlob* generate_empty_safepoint_blob() +{ + CodeBuffer buffer("handler_blob", 0, 0); + return SafepointBlob::create(&buffer, NULL, 0); +} + +void SharedRuntime::generate_stubs() +{ + _wrong_method_blob = + generate_empty_runtime_stub("wrong_method_stub"); + _ic_miss_blob = + generate_empty_runtime_stub("ic_miss_stub"); + _resolve_opt_virtual_call_blob = + generate_empty_runtime_stub("resolve_opt_virtual_call"); + _resolve_virtual_call_blob = + generate_empty_runtime_stub("resolve_virtual_call"); + _resolve_static_call_blob = + generate_empty_runtime_stub("resolve_static_call"); + + _polling_page_safepoint_handler_blob = + generate_empty_safepoint_blob(); + _polling_page_return_handler_blob = + generate_empty_safepoint_blob(); +} + +int SharedRuntime::c_calling_convention(const BasicType *sig_bt, + VMRegPair *regs, + int total_args_passed) +{ + Unimplemented(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/sharkFrame_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,77 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// | ... | +// +--------------------+ ------------------ +// | stack slot n-1 | low addresses +// | ... | +// | stack slot 0 | +// | monitor m-1 | +// | ... | +// | monitor 0 | +// | oop_tmp | +// | method | +// | unextended_sp | +// | pc | +// | frame_type | +// | next_frame | high addresses +// +--------------------+ ------------------ +// | ... | + +class SharkFrame : public ZeroFrame { + friend class ZeroStackPrinter; + friend class SharkFunction; + + private: + SharkFrame() : ZeroFrame() + { + ShouldNotCallThis(); + } + + protected: + enum Layout { + pc_off = jf_header_words, + unextended_sp_off, + method_off, + oop_tmp_off, + header_words + }; + + public: + address pc() const + { + return (address) value_of_word(pc_off); + } + + intptr_t* unextended_sp() const + { + return (intptr_t *) value_of_word(unextended_sp_off); + } + + methodOop method() const + { + return (methodOop) value_of_word(method_off); + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/stackPrinter_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,293 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include <interpreterRuntime.hpp> +#include <scopeDesc.hpp> + +class ZeroStackPrinter { + private: + outputStream* _st; + char* _buf; + int _buflen; + + public: + ZeroStackPrinter(outputStream *st, char *buf, int buflen) + : _st(st), _buf(buf), _buflen(buflen) {} + + void print(JavaThread *thread) + { + intptr_t *lo_addr = thread->zero_stack()->sp(); + if (!lo_addr) { + _st->print_cr(" stack not set up"); + return; + } + + intptr_t *hi_addr = (intptr_t *) thread->top_zero_frame(); + if (!hi_addr) { + _st->print_cr("no frames pushed"); + return; + } + assert(hi_addr >= lo_addr, "corrupted stack"); + + bool top_frame = true; + while (hi_addr) { + if (!top_frame) + _st->cr(); + ZeroFrame *frame = (ZeroFrame *) hi_addr; + for (intptr_t *addr = lo_addr; addr <= hi_addr; addr++) + print_word(frame, addr, top_frame); + lo_addr = hi_addr + 1; + hi_addr = *(intptr_t **) hi_addr; + top_frame = false; + } + } + + private: + void print_word(ZeroFrame *frame, intptr_t *addr, bool top_frame) + { + const char *field = NULL; + const char *value = NULL; + + int word = (intptr_t *) frame - addr; + switch (word) { + case ZeroFrame::next_frame_off: + field = "next_frame"; + break; + case ZeroFrame::frame_type_off: + field = "frame_type"; + switch (*addr) { + case ZeroFrame::ENTRY_FRAME: + value = "ENTRY_FRAME"; + break; + case ZeroFrame::INTERPRETER_FRAME: + value = "INTERPRETER_FRAME"; + break; + case ZeroFrame::SHARK_FRAME: + value = "SHARK_FRAME"; + break; + case ZeroFrame::DEOPTIMIZER_FRAME: + value = "DEOPTIMIZER_FRAME"; + break; + } + break; + } + + if (!field) { + if (frame->is_entry_frame()) { + if (word == EntryFrame::call_wrapper_off) { + field = "call_wrapper"; + } + else { + snprintf(_buf, _buflen, "local[%d]", word - 3); + field = _buf; + } + } + if (frame->is_interpreter_frame()) { + interpreterState istate = + ((InterpreterFrame *) frame)->interpreter_state(); + bool is_valid = istate->self_link() == istate; + + if (addr >= (intptr_t *) istate) { + field = istate->name_of_field_at_address((address) addr); + if (field) { + if (is_valid && !strcmp(field, "_method")) { + value = istate->method()->name_and_sig_as_C_string(_buf,_buflen); + field = "istate->_method"; + } + else if (is_valid && !strcmp(field, "_bcp") && istate->bcp()) { + snprintf(_buf, _buflen, "%p (bci %d)", istate->bcp(), + istate->method()->bci_from(istate->bcp())); + value = _buf; + field = "istate->_bcp"; + } + else { + snprintf(_buf, _buflen, "%sistate->%s", + field[strlen(field) - 1] == ')' ? "(": "", field); + field = _buf; + } + } + else if (addr == (intptr_t *) istate) { + field = "(vtable for istate)"; + } + } + else if (is_valid) { + intptr_t *monitor_base = (intptr_t *) istate->monitor_base(); + if (addr >= istate->stack_base() && addr < monitor_base) { + int monitor_size = frame::interpreter_frame_monitor_size(); + int last_index = + (monitor_base - istate->stack_base()) / monitor_size - 1; + int index = + last_index - (addr - istate->stack_base()) / monitor_size; + intptr_t monitor = (intptr_t) (istate->monitor_base() - 1 - index); + intptr_t offset = (intptr_t) addr - monitor; + + if (offset == BasicObjectLock::obj_offset_in_bytes()) { + snprintf(_buf, _buflen, "monitor[%d]->_obj", index); + field = _buf; + } + else if (offset == BasicObjectLock::lock_offset_in_bytes()) { + snprintf(_buf, _buflen, "monitor[%d]->_lock", index); + field = _buf; + } + } + else if (addr < istate->stack_base()) { + if (istate->method()->is_native()) { + address hA = istate->method()->signature_handler(); + if (hA != NULL) { + if (hA != (address)InterpreterRuntime::slow_signature_handler){ + InterpreterRuntime::SignatureHandler *handler = + InterpreterRuntime::SignatureHandler::from_handlerAddr(hA); + + intptr_t *params = + istate->stack_base() - handler->argument_count(); + + if (addr >= params) { + int param = addr - params; + const char *desc = ""; + if (param == 0) + desc = " (JNIEnv)"; + else if (param == 1) { + if (istate->method()->is_static()) + desc = " (mirror)"; + else + desc = " (this)"; + } + snprintf(_buf, _buflen, "parameter[%d]%s", param, desc); + field = _buf; + } + else { + for (int i = 0; i < handler->argument_count(); i++) { + if (params[i] == (intptr_t) addr) { + snprintf(_buf, _buflen, "unboxed parameter[%d]", i); + field = _buf; + break; + } + } + } + } + } + } + else { + snprintf(_buf, _buflen, "%s[" INTPTR_FORMAT "]", + top_frame ? "stack_word" : "local", + istate->stack_base() - addr - 1); + field = _buf; + } + } + } + } + if (frame->is_shark_frame()) { + SharkFrame *sf = frame->as_shark_frame(); + methodOop method = sf->method(); + + if (word == SharkFrame::pc_off) { + field = "pc"; + if (method->is_oop()) { + nmethod *code = method->code(); + address pc = sf->pc(); + if (code->pc_desc_at(pc)) { + SimpleScopeDesc ssd(code, pc); + snprintf(_buf, _buflen, "%p (bci %d)", pc, ssd.bci()); + value = _buf; + } + } + } + else if (word == SharkFrame::unextended_sp_off) { + field = "unextended_sp"; + } + else if (word == SharkFrame::method_off) { + field = "method"; + if (method->is_oop()) + value = method->name_and_sig_as_C_string(_buf, _buflen); + } + else if (word == SharkFrame::oop_tmp_off) { + field = "oop_tmp"; + } + else { + SharkFrame *sf = (SharkFrame *) frame; + intptr_t *monitor_base = + (intptr_t *) frame - SharkFrame::header_words + 1; + intptr_t *stack_base = + sf->unextended_sp() + sf->method()->max_stack(); + + if (addr >= stack_base && addr < monitor_base) { + int monitor_size = frame::interpreter_frame_monitor_size(); + int last_index = (monitor_base - stack_base) / monitor_size - 1; + int index = last_index - (addr - stack_base) / monitor_size; + intptr_t monitor = + (intptr_t) ((BasicObjectLock *) monitor_base - 1 - index); + intptr_t offset = (intptr_t) addr - monitor; + + if (offset == BasicObjectLock::obj_offset_in_bytes()) { + snprintf(_buf, _buflen, "monitor[%d]->_obj", index); + field = _buf; + } + else if (offset == BasicObjectLock::lock_offset_in_bytes()) { + snprintf(_buf, _buflen, "monitor[%d]->_lock", index); + field = _buf; + } + } + else { + snprintf(_buf, _buflen, "%s[" INTPTR_FORMAT "]", + top_frame ? "stack_word" : "local", + stack_base - addr - 1); + field = _buf; + } + } + } + } + + if (!field) { + snprintf(_buf, _buflen, "word[%d]", word); + field = _buf; + } + _st->print(" %p: %-21s = ", addr, field); + if (value) + _st->print_cr("%s", value); + else + _st->print_cr(PTR_FORMAT, *addr); + } +}; + +#ifndef PRODUCT +extern "C" { + void print_zero_threads() { + char buf[O_BUFLEN]; + ZeroStackPrinter zsp(tty, buf, sizeof(buf)); + + for (JavaThread *t = Threads::first(); t; t = t->next()) { + tty->print(PTR_FORMAT, t); + tty->print(" "); + t->print_on_error(tty, buf, sizeof(buf)); + tty->cr(); + tty->cr(); + + zsp.print(t); + if (t->next()) + tty->cr(); + } + } +} +#endif // !PRODUCT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/stack_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,219 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class ZeroStack { + private: + intptr_t *_base; // the last available word + intptr_t *_top; // the word past the end of the stack + intptr_t *_sp; // the top word on the stack + + public: + ZeroStack() + : _base(NULL), _top(NULL), _sp(NULL) {} + + bool needs_setup() const + { + return _base == NULL; + } + + void setup(void *mem, size_t size) + { + assert(needs_setup(), "already set up"); + assert(!(size & WordAlignmentMask), "unaligned"); + + _base = (intptr_t *) mem; + _top = _base + (size >> LogBytesPerWord); + _sp = _top; + } + + void teardown() + { + assert(!needs_setup(), "not set up"); + assert(_sp == _top, "stuff on stack at teardown"); + + _base = NULL; + _top = NULL; + _sp = NULL; + } + + intptr_t *sp() const + { + return _sp; + } + + void set_sp(intptr_t *new_sp) + { + assert(_top >= new_sp && new_sp >= _base, "bad stack pointer"); + _sp = new_sp; + } + + int available_words() const + { + return _sp - _base; + } + + void push(intptr_t value) + { + assert(_sp > _base, "stack overflow"); + *(--_sp) = value; + } + + intptr_t pop() + { + assert(_sp < _top, "stack underflow"); + return *(_sp++); + } + + void *alloc(size_t size) + { + int count = align_size_up(size, wordSize) >> LogBytesPerWord; + assert(count <= available_words(), "stack overflow"); + return _sp -= count; + } + + public: + static ByteSize base_offset() + { + return byte_offset_of(ZeroStack, _base); + } + + static ByteSize top_offset() + { + return byte_offset_of(ZeroStack, _top); + } + + static ByteSize sp_offset() + { + return byte_offset_of(ZeroStack, _sp); + } +}; + + +class EntryFrame; +class InterpreterFrame; +class SharkFrame; +class DeoptimizerFrame; + +// +// | ... | +// +--------------------+ ------------------ +// | ... | low addresses +// | frame_type | +// | next_frame | high addresses +// +--------------------+ ------------------ +// | ... | + +class ZeroFrame { + friend class frame; + friend class ZeroStackPrinter; + + protected: + ZeroFrame() + { + ShouldNotCallThis(); + } + + enum Layout { + next_frame_off, + frame_type_off, + jf_header_words + }; + + enum FrameType { + ENTRY_FRAME = 1, + INTERPRETER_FRAME, + SHARK_FRAME, + DEOPTIMIZER_FRAME + }; + + protected: + intptr_t *addr_of_word(int offset) const + { + return (intptr_t *) this - offset; + } + + intptr_t value_of_word(int offset) const + { + return *addr_of_word(offset); + } + + public: + ZeroFrame *next() const + { + return (ZeroFrame *) value_of_word(next_frame_off); + } + + protected: + FrameType type() const + { + return (FrameType) value_of_word(frame_type_off); + } + + public: + bool is_entry_frame() const + { + return type() == ENTRY_FRAME; + } + + bool is_interpreter_frame() const + { + return type() == INTERPRETER_FRAME; + } + + bool is_shark_frame() const + { + return type() == SHARK_FRAME; + } + + bool is_deoptimizer_frame() const + { + return type() == DEOPTIMIZER_FRAME; + } + + public: + EntryFrame *as_entry_frame() const + { + assert(is_entry_frame(), "should be"); + return (EntryFrame *) this; + } + + InterpreterFrame *as_interpreter_frame() const + { + assert(is_interpreter_frame(), "should be"); + return (InterpreterFrame *) this; + } + + SharkFrame *as_shark_frame() const + { + assert(is_shark_frame(), "should be"); + return (SharkFrame *) this; + } + + DeoptimizerFrame *as_deoptimizer_frame() const + { + assert(is_deoptimizer_frame(), "should be"); + return (DeoptimizerFrame *) this; + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/stubGenerator_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,260 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_stubGenerator_zero.cpp.incl" + +// Declaration and definition of StubGenerator (no .hpp file). +// For a more detailed description of the stub routine structure +// see the comment in stubRoutines.hpp + +class StubGenerator: public StubCodeGenerator +{ + private: + // The call stub is used to call Java from C + static void call_stub( + JavaCallWrapper *call_wrapper, + intptr_t* result, + BasicType result_type, + methodOop method, + address entry_point, + intptr_t* parameters, + int parameter_words, + TRAPS) + { + JavaThread *thread = (JavaThread *) THREAD; + ZeroStack *stack = thread->zero_stack(); + + // Make sure we have no pending exceptions + assert(!HAS_PENDING_EXCEPTION, "call_stub called with pending exception"); + + // Set up the stack if necessary + bool stack_needs_teardown = false; + if (stack->needs_setup()) { + size_t stack_used = thread->stack_base() - (address) &stack_used; + size_t stack_free = thread->stack_size() - stack_used; + size_t zero_stack_size = align_size_down(stack_free / 2, wordSize); + + stack->setup(alloca(zero_stack_size), zero_stack_size); + stack_needs_teardown = true; + } + + // Allocate and initialize our frame + thread->push_zero_frame( + EntryFrame::build(stack, parameters, parameter_words, call_wrapper)); + + // Make the call + Interpreter::invoke_method(method, entry_point, THREAD); + + // Store result depending on type + if (!HAS_PENDING_EXCEPTION) { + switch (result_type) { + case T_INT: + *(jint *) result = *(jint *) stack->sp(); + break; + case T_LONG: + *(jlong *) result = *(jlong *) stack->sp(); + break; + case T_FLOAT: + *(jfloat *) result = *(jfloat *) stack->sp(); + break; + case T_DOUBLE: + *(jdouble *) result = *(jdouble *) stack->sp(); + break; + case T_OBJECT: + *(oop *) result = *(oop *) stack->sp(); + break; + default: + ShouldNotReachHere(); + } + } + + // Unwind our frame + thread->pop_zero_frame(); + + // Tear down the stack if necessary + if (stack_needs_teardown) + stack->teardown(); + } + + // These stubs get called from some dumb test routine. + // I'll write them properly when they're called from + // something that's actually doing something. + static void fake_arraycopy_stub(address src, address dst, int count) + { + assert(count == 0, "huh?"); + } + + void generate_arraycopy_stubs() + { + // Call the conjoint generation methods immediately after + // the disjoint ones so that short branches from the former + // to the latter can be generated. + StubRoutines::_jbyte_disjoint_arraycopy = (address) fake_arraycopy_stub; + StubRoutines::_jbyte_arraycopy = (address) fake_arraycopy_stub; + + StubRoutines::_jshort_disjoint_arraycopy = (address) fake_arraycopy_stub; + StubRoutines::_jshort_arraycopy = (address) fake_arraycopy_stub; + + StubRoutines::_jint_disjoint_arraycopy = (address) fake_arraycopy_stub; + StubRoutines::_jint_arraycopy = (address) fake_arraycopy_stub; + + StubRoutines::_jlong_disjoint_arraycopy = (address) fake_arraycopy_stub; + StubRoutines::_jlong_arraycopy = (address) fake_arraycopy_stub; + + StubRoutines::_oop_disjoint_arraycopy = UnimplementedStub(); + StubRoutines::_oop_arraycopy = UnimplementedStub(); + + StubRoutines::_checkcast_arraycopy = UnimplementedStub(); + StubRoutines::_unsafe_arraycopy = UnimplementedStub(); + StubRoutines::_generic_arraycopy = UnimplementedStub(); + + // We don't generate specialized code for HeapWord-aligned source + // arrays, so just use the code we've already generated + StubRoutines::_arrayof_jbyte_disjoint_arraycopy = + StubRoutines::_jbyte_disjoint_arraycopy; + StubRoutines::_arrayof_jbyte_arraycopy = + StubRoutines::_jbyte_arraycopy; + + StubRoutines::_arrayof_jshort_disjoint_arraycopy = + StubRoutines::_jshort_disjoint_arraycopy; + StubRoutines::_arrayof_jshort_arraycopy = + StubRoutines::_jshort_arraycopy; + + StubRoutines::_arrayof_jint_disjoint_arraycopy = + StubRoutines::_jint_disjoint_arraycopy; + StubRoutines::_arrayof_jint_arraycopy = + StubRoutines::_jint_arraycopy; + + StubRoutines::_arrayof_jlong_disjoint_arraycopy = + StubRoutines::_jlong_disjoint_arraycopy; + StubRoutines::_arrayof_jlong_arraycopy = + StubRoutines::_jlong_arraycopy; + + StubRoutines::_arrayof_oop_disjoint_arraycopy = + StubRoutines::_oop_disjoint_arraycopy; + StubRoutines::_arrayof_oop_arraycopy = + StubRoutines::_oop_arraycopy; + } + + void generate_initial() + { + // Generates all stubs and initializes the entry points + + // entry points that exist in all platforms Note: This is code + // that could be shared among different platforms - however the + // benefit seems to be smaller than the disadvantage of having a + // much more complicated generator structure. See also comment in + // stubRoutines.hpp. + + StubRoutines::_forward_exception_entry = UnimplementedStub(); + StubRoutines::_call_stub_entry = (address) call_stub; + StubRoutines::_catch_exception_entry = UnimplementedStub(); + + // atomic calls + StubRoutines::_atomic_xchg_entry = UnimplementedStub(); + StubRoutines::_atomic_xchg_ptr_entry = UnimplementedStub(); + StubRoutines::_atomic_cmpxchg_entry = UnimplementedStub(); + StubRoutines::_atomic_cmpxchg_ptr_entry = UnimplementedStub(); + StubRoutines::_atomic_cmpxchg_long_entry = UnimplementedStub(); + StubRoutines::_atomic_add_entry = UnimplementedStub(); + StubRoutines::_atomic_add_ptr_entry = UnimplementedStub(); + StubRoutines::_fence_entry = UnimplementedStub(); + + // amd64 does this here, sparc does it in generate_all() + StubRoutines::_handler_for_unsafe_access_entry = + UnimplementedStub(); + } + + void generate_all() + { + // Generates all stubs and initializes the entry points + + // These entry points require SharedInfo::stack0 to be set up in + // non-core builds and need to be relocatable, so they each + // fabricate a RuntimeStub internally. + StubRoutines::_throw_AbstractMethodError_entry = + UnimplementedStub(); + + StubRoutines::_throw_ArithmeticException_entry = + UnimplementedStub(); + + StubRoutines::_throw_NullPointerException_entry = + UnimplementedStub(); + + StubRoutines::_throw_NullPointerException_at_call_entry = + UnimplementedStub(); + + StubRoutines::_throw_StackOverflowError_entry = + UnimplementedStub(); + + // support for verify_oop (must happen after universe_init) + StubRoutines::_verify_oop_subroutine_entry = + UnimplementedStub(); + + // arraycopy stubs used by compilers + generate_arraycopy_stubs(); + } + + public: + StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) + { + if (all) { + generate_all(); + } else { + generate_initial(); + } + } +}; + +void StubGenerator_generate(CodeBuffer* code, bool all) +{ + StubGenerator g(code, all); +} + +EntryFrame *EntryFrame::build(ZeroStack* stack, + const intptr_t* parameters, + int parameter_words, + JavaCallWrapper* call_wrapper) +{ + if (header_words + parameter_words > stack->available_words()) { + Unimplemented(); + } + + stack->push(0); // next_frame, filled in later + intptr_t *fp = stack->sp(); + assert(fp - stack->sp() == next_frame_off, "should be"); + + stack->push(ENTRY_FRAME); + assert(fp - stack->sp() == frame_type_off, "should be"); + + stack->push((intptr_t) call_wrapper); + assert(fp - stack->sp() == call_wrapper_off, "should be"); + + for (int i = 0; i < parameter_words; i++) + stack->push(parameters[i]); + + return (EntryFrame *) fp; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/stubRoutines_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,31 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_stubRoutines_zero.cpp.incl" + +#ifdef IA32 +address StubRoutines::x86::_call_stub_compiled_return = NULL; +#endif // IA32
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/stubRoutines_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,55 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + // This file holds the platform specific parts of the StubRoutines + // definition. See stubRoutines.hpp for a description on how to + // extend it. + + public: + static address call_stub_return_pc() + { + return (address) -1; + } + + static bool returns_to_call_stub(address return_pc) + { + return return_pc == call_stub_return_pc(); + } + + enum platform_dependent_constants + { + code_size1 = 0, // The assembler will fail with a guarantee + code_size2 = 0 // if these are too small. Simply increase + }; // them if that happens. + +#ifdef IA32 + class x86 + { + friend class VMStructs; + + private: + static address _call_stub_compiled_return; + }; +#endif // IA32
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/templateInterpreterGenerator_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/templateInterpreter_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/templateInterpreter_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/templateTable_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/templateTable_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/vmStructs_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,52 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// These are the CPU-specific fields, types and integer +// constants required by the Serviceability Agent. This file is +// referenced by vmStructs.cpp. + +#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ + + /* NOTE that we do not use the last_entry() macro here; it is used */ + /* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */ + /* be present there) */ + +#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ + + /* NOTE that we do not use the last_entry() macro here; it is used */ + /* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must */ + /* be present there) */ + +#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ + + /* NOTE that we do not use the last_entry() macro here; it is used */ + /* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */ + /* be present there) */ + +#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ + + /* NOTE that we do not use the last_entry() macro here; it is used */ + /* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */ + /* be present there) */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/vm_version_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/vm_version_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class VM_Version : public Abstract_VM_Version { + public: + static const char* cpu_features() + { + return ""; + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/vmreg_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,67 @@ +/* + * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_vmreg_zero.cpp.incl" + +void VMRegImpl::set_regName() +{ + int i = 0; + Register reg = ::as_Register(0); + for ( ; i < ConcreteRegisterImpl::max_gpr ; ) { + regName[i++] = reg->name(); + reg = reg->successor(); + } + FloatRegister freg = ::as_FloatRegister(0); + for ( ; i < ConcreteRegisterImpl::max_fpr ; ) { + regName[i++] = freg->name(); + freg = freg->successor(); + } + assert(i == ConcreteRegisterImpl::number_of_registers, "fix this"); +} + +bool VMRegImpl::is_Register() +{ + return value() >= 0 && + value() < ConcreteRegisterImpl::max_gpr; +} + +bool VMRegImpl::is_FloatRegister() +{ + return value() >= ConcreteRegisterImpl::max_gpr && + value() < ConcreteRegisterImpl::max_fpr; +} + +Register VMRegImpl::as_Register() +{ + assert(is_Register(), "must be"); + return ::as_Register(value()); +} + +FloatRegister VMRegImpl::as_FloatRegister() +{ + assert(is_FloatRegister(), "must be" ); + return ::as_FloatRegister(value() - ConcreteRegisterImpl::max_gpr); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/vmreg_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,29 @@ +/* + * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + bool is_Register(); + Register as_Register(); + + bool is_FloatRegister(); + FloatRegister as_FloatRegister();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/vmreg_zero.inline.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ +inline VMReg RegisterImpl::as_VMReg() +{ + return VMRegImpl::as_VMReg(encoding()); +} +inline VMReg FloatRegisterImpl::as_VMReg() +{ + return VMRegImpl::as_VMReg(encoding() + ConcreteRegisterImpl::max_gpr); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/zero/vm/vtableStubs_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,47 @@ +/* + * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_vtableStubs_zero.cpp.incl" + +VtableStub* VtableStubs::create_vtable_stub(int vtable_index) +{ + Unimplemented(); +} + +VtableStub* VtableStubs::create_itable_stub(int vtable_index) +{ + Unimplemented(); +} + +int VtableStub::pd_code_size_limit(bool is_vtable_stub) +{ + Unimplemented(); +} + +int VtableStub::pd_code_alignment() +{ + Unimplemented(); +}
--- a/src/os/linux/vm/os_linux.cpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/os/linux/vm/os_linux.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -176,7 +176,9 @@ #endif // Cpu architecture string -#if defined(IA64) +#if defined(ZERO) +static char cpu_arch[] = ZERO_LIBARCH; +#elif defined(IA64) static char cpu_arch[] = "ia64"; #elif defined(IA32) static char cpu_arch[] = "i386"; @@ -1743,7 +1745,14 @@ {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"}, {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"}, - {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"} + {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"}, + {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"}, + {EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"}, + {EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"}, + {EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"}, + {EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"}, + {EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"}, + {EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"} }; #if (defined IA32) @@ -1760,9 +1769,23 @@ static Elf32_Half running_arch_code=EM_PPC64; #elif (defined __powerpc__) static Elf32_Half running_arch_code=EM_PPC; + #elif (defined ARM) + static Elf32_Half running_arch_code=EM_ARM; + #elif (defined S390) + static Elf32_Half running_arch_code=EM_S390; + #elif (defined ALPHA) + static Elf32_Half running_arch_code=EM_ALPHA; + #elif (defined MIPSEL) + static Elf32_Half running_arch_code=EM_MIPS_RS3_LE; + #elif (defined PARISC) + static Elf32_Half running_arch_code=EM_PARISC; + #elif (defined MIPS) + static Elf32_Half running_arch_code=EM_MIPS; + #elif (defined M68K) + static Elf32_Half running_arch_code=EM_68K; #else #error Method os::dll_load requires that one of following is defined:\ - IA32, AMD64, IA64, __sparc, __powerpc__ + IA32, AMD64, IA64, __sparc, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K #endif // Identify compatability class for VM's architecture and library's architecture @@ -1794,10 +1817,12 @@ return NULL; } +#ifndef S390 if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) { ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)"); return NULL; } +#endif // !S390 if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) { if ( lib_arch.name!=NULL ) { @@ -2586,7 +2611,9 @@ // format has been changed), we'll use the largest page size supported by // the processor. +#ifndef ZERO _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M); +#endif // ZERO FILE *fp = fopen("/proc/meminfo", "r"); if (fp) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/assembler_linux_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,319 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Implementation of class atomic + +#ifdef M68K + +/* + * __m68k_cmpxchg + * + * Atomically store newval in *ptr if *ptr is equal to oldval for user space. + * Returns newval on success and oldval if no exchange happened. + * This implementation is processor specific and works on + * 68020 68030 68040 and 68060. + * + * It will not work on ColdFire, 68000 and 68010 since they lack the CAS + * instruction. + * Using a kernelhelper would be better for arch complete implementation. + * + */ + +static inline int __m68k_cmpxchg(int oldval, int newval, volatile int *ptr) +{ + int ret; + __asm __volatile ("cas%.l %0,%2,%1" + : "=d" (ret), "+m" (*(ptr)) + : "d" (newval), "0" (oldval)); + return ret; +} + +/* Perform an atomic compare and swap: if the current value of `*PTR' + is OLDVAL, then write NEWVAL into `*PTR'. Return the contents of + `*PTR' before the operation.*/ +static inline int m68k_compare_and_swap(volatile int *ptr, + int oldval, + int newval) +{ + for (;;) + { + int prev = *ptr; + if (prev != oldval) + return prev; + + if (__m68k_cmpxchg (prev, newval, ptr) == newval) + // Success. + return prev; + + // We failed even though prev == oldval. Try again. + } +} + +/* Atomically add an int to memory. */ +static inline int m68k_add_and_fetch(volatile int *ptr, int add_value) +{ + for (;;) + { + // Loop until success. + + int prev = *ptr; + + if (__m68k_cmpxchg (prev, prev + add_value, ptr) == prev + add_value) + return prev + add_value; + } +} + +/* Atomically write VALUE into `*PTR' and returns the previous + contents of `*PTR'. */ +static inline int m68k_lock_test_and_set(volatile int *ptr, int newval) +{ + for (;;) + { + // Loop until success. + int prev = *ptr; + + if (__m68k_cmpxchg (prev, newval, ptr) == prev) + return prev; + } +} +#endif // M68K + +#ifdef ARM + +/* + * __kernel_cmpxchg + * + * Atomically store newval in *ptr if *ptr is equal to oldval for user space. + * Return zero if *ptr was changed or non-zero if no exchange happened. + * The C flag is also set if *ptr was changed to allow for assembly + * optimization in the calling code. + * + */ + +typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr); +#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0) + + + +/* Perform an atomic compare and swap: if the current value of `*PTR' + is OLDVAL, then write NEWVAL into `*PTR'. Return the contents of + `*PTR' before the operation.*/ +static inline int arm_compare_and_swap(volatile int *ptr, + int oldval, + int newval) +{ + for (;;) + { + int prev = *ptr; + if (prev != oldval) + return prev; + + if (__kernel_cmpxchg (prev, newval, ptr) == 0) + // Success. + return prev; + + // We failed even though prev == oldval. Try again. + } +} + +/* Atomically add an int to memory. */ +static inline int arm_add_and_fetch(volatile int *ptr, int add_value) +{ + for (;;) + { + // Loop until a __kernel_cmpxchg succeeds. + + int prev = *ptr; + + if (__kernel_cmpxchg (prev, prev + add_value, ptr) == 0) + return prev + add_value; + } +} + +/* Atomically write VALUE into `*PTR' and returns the previous + contents of `*PTR'. */ +static inline int arm_lock_test_and_set(volatile int *ptr, int newval) +{ + for (;;) + { + // Loop until a __kernel_cmpxchg succeeds. + int prev = *ptr; + + if (__kernel_cmpxchg (prev, newval, ptr) == 0) + return prev; + } +} +#endif // ARM + +inline void Atomic::store(jint store_value, volatile jint* dest) +{ + *dest = store_value; +} + +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) +{ + *dest = store_value; +} + +inline jint Atomic::add(jint add_value, volatile jint* dest) +{ +#ifdef ARM + return arm_add_and_fetch(dest, add_value); +#else +#ifdef M68K + return m68k_add_and_fetch(dest, add_value); +#else + return __sync_add_and_fetch(dest, add_value); +#endif // M68K +#endif // ARM +} + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) +{ +#ifdef ARM + return arm_add_and_fetch(dest, add_value); +#else +#ifdef M68K + return m68k_add_and_fetch(dest, add_value); +#else + return __sync_add_and_fetch(dest, add_value); +#endif // M68K +#endif // ARM +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) +{ + return (void *) add_ptr(add_value, (volatile intptr_t *) dest); +} + +inline void Atomic::inc(volatile jint* dest) +{ + add(1, dest); +} + +inline void Atomic::inc_ptr(volatile intptr_t* dest) +{ + add_ptr(1, dest); +} + +inline void Atomic::inc_ptr(volatile void* dest) +{ + add_ptr(1, dest); +} + +inline void Atomic::dec(volatile jint* dest) +{ + add(-1, dest); +} + +inline void Atomic::dec_ptr(volatile intptr_t* dest) +{ + add_ptr(-1, dest); +} + +inline void Atomic::dec_ptr(volatile void* dest) +{ + add_ptr(-1, dest); +} + +inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) +{ +#ifdef ARM + return arm_lock_test_and_set(dest, exchange_value); +#else +#ifdef M68K + return m68k_lock_test_and_set(dest, exchange_value); +#else + // __sync_lock_test_and_set is a bizarrely named atomic exchange + // operation. Note that some platforms only support this with the + // limitation that the only valid value to store is the immediate + // constant 1. There is a test for this in JNI_CreateJavaVM(). + return __sync_lock_test_and_set (dest, exchange_value); +#endif // M68K +#endif // ARM +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, + volatile intptr_t* dest) { +#ifdef ARM + return arm_lock_test_and_set(dest, exchange_value); +#else +#ifdef M68K + return m68k_lock_test_and_set(dest, exchange_value); +#else + return __sync_lock_test_and_set (dest, exchange_value); +#endif // M68K +#endif // ARM +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) +{ + return (void *) xchg_ptr((intptr_t) exchange_value, + (volatile intptr_t*) dest); +} + +inline jint Atomic::cmpxchg(jint exchange_value, + volatile jint* dest, + jint compare_value) { +#ifdef ARM + return arm_compare_and_swap(dest, compare_value, exchange_value); +#else +#ifdef M68K + return m68k_compare_and_swap(dest, compare_value, exchange_value); +#else + return __sync_val_compare_and_swap(dest, compare_value, exchange_value); +#endif // M68K +#endif // ARM +} + +inline jlong Atomic::cmpxchg(jlong exchange_value, + volatile jlong* dest, + jlong compare_value) { + + return __sync_val_compare_and_swap(dest, compare_value, exchange_value); +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, + volatile intptr_t* dest, + intptr_t compare_value) { +#ifdef ARM + return arm_compare_and_swap(dest, compare_value, exchange_value); +#else +#ifdef M68K + return m68k_compare_and_swap(dest, compare_value, exchange_value); +#else + return __sync_val_compare_and_swap(dest, compare_value, exchange_value); +#endif // M68K +#endif // ARM +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, + volatile void* dest, + void* compare_value) { + + return (void *) cmpxchg_ptr((intptr_t) exchange_value, + (volatile intptr_t*) dest, + (intptr_t) compare_value); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/bytes_linux_zero.inline.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,43 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Efficient swapping of data bytes from Java byte +// ordering to native byte ordering and vice versa. + +#include <byteswap.h> + +inline u2 Bytes::swap_u2(u2 x) +{ + return bswap_16(x); +} + +inline u4 Bytes::swap_u4(u4 x) +{ + return bswap_32(x); +} + +inline u8 Bytes::swap_u8(u8 x) +{ + return bswap_64(x); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// +// Set the default values for platform dependent flags used by the +// runtime system. See globals.hpp for details of what they do. +// + +define_pd_global(bool, DontYieldALot, false); +#ifdef _LP64 +define_pd_global(intx, ThreadStackSize, 1536); +define_pd_global(intx, VMThreadStackSize, 1024); +#else +define_pd_global(intx, ThreadStackSize, 1024); +define_pd_global(intx, VMThreadStackSize, 512); +#endif // _LP64 +define_pd_global(intx, SurvivorRatio, 8); +define_pd_global(intx, CompilerThreadStackSize, 0); +define_pd_global(uintx, JVMInvokeMethodSlack, 8192); + +define_pd_global(bool, UseVectoredExceptions, false); +// Only used on 64 bit platforms +define_pd_global(uintx, HeapBaseMinAddress, 2*G);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/interp_masm_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,35 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// This file specializes the assember with interpreter-specific macros + +class InterpreterMacroAssembler : public MacroAssembler { + public: + InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {} + RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, Register tmp, int offset) + { + Unimplemented(); + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/interpreterGenerator_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,38 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + + // Generation of Interpreter + // + friend class AbstractInterpreterGenerator; + + private: + address generate_normal_entry(bool synchronized); + address generate_native_entry(bool synchronized); + address generate_abstract_entry(); + address generate_math_entry(AbstractInterpreter::MethodKind kind); + address generate_empty_entry(); + address generate_accessor_entry(); + address generate_method_handle_entry();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,176 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#ifdef ARM + +/* + * ARM Kernel helper for memory barrier. + * Using __asm __volatile ("":::"memory") does not work reliable on ARM + * and gcc __sync_synchronize(); implementation does not use the kernel + * helper for all gcc versions so it is unreliable to use as well. + */ +typedef void (__kernel_dmb_t) (void); +#define __kernel_dmb (*(__kernel_dmb_t *) 0xffff0fa0) + +#define FULL_MEM_BARRIER __kernel_dmb() +#define READ_MEM_BARRIER __kernel_dmb() +#define WRITE_MEM_BARRIER __kernel_dmb() + +#else // ARM + +#define FULL_MEM_BARRIER __sync_synchronize() + +#ifdef PPC + +#define READ_MEM_BARRIER __asm __volatile ("isync":::"memory") +#ifdef __NO_LWSYNC__ +#define WRITE_MEM_BARRIER __asm __volatile ("sync":::"memory") +#else +#define WRITE_MEM_BARRIER __asm __volatile ("lwsync":::"memory") +#endif + +#else // PPC + +#define READ_MEM_BARRIER __asm __volatile ("":::"memory") +#define WRITE_MEM_BARRIER __asm __volatile ("":::"memory") + +#endif // PPC + +#endif // ARM + + +inline void OrderAccess::loadload() { acquire(); } +inline void OrderAccess::storestore() { release(); } +inline void OrderAccess::loadstore() { acquire(); } +inline void OrderAccess::storeload() { fence(); } + +inline void OrderAccess::acquire() +{ + READ_MEM_BARRIER; +} + +inline void OrderAccess::release() +{ + WRITE_MEM_BARRIER; +} + +inline void OrderAccess::fence() +{ + FULL_MEM_BARRIER; +} + +inline jbyte OrderAccess::load_acquire(volatile jbyte* p) { jbyte data = *p; acquire(); return data; } +inline jshort OrderAccess::load_acquire(volatile jshort* p) { jshort data = *p; acquire(); return data; } +inline jint OrderAccess::load_acquire(volatile jint* p) { jint data = *p; acquire(); return data; } +inline jlong OrderAccess::load_acquire(volatile jlong* p) +{ + jlong tmp; + os::atomic_copy64(p, &tmp); + acquire(); + return tmp; +} +inline jubyte OrderAccess::load_acquire(volatile jubyte* p) { jubyte data = *p; acquire(); return data; } +inline jushort OrderAccess::load_acquire(volatile jushort* p) { jushort data = *p; acquire(); return data; } +inline juint OrderAccess::load_acquire(volatile juint* p) { juint data = *p; acquire(); return data; } +inline julong OrderAccess::load_acquire(volatile julong* p) +{ + julong tmp; + os::atomic_copy64(p, &tmp); + acquire(); + return tmp; +} +inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { jfloat data = *p; acquire(); return data; } +inline jdouble OrderAccess::load_acquire(volatile jdouble* p) +{ + jdouble tmp; + os::atomic_copy64(p, &tmp); + acquire(); + return tmp; +} + +inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) +{ + intptr_t data = *p; + acquire(); + return data; +} +inline void* OrderAccess::load_ptr_acquire(volatile void* p) +{ + void *data = *(void* volatile *)p; + acquire(); + return data; +} +inline void* OrderAccess::load_ptr_acquire(const volatile void* p) +{ + void *data = *(void* const volatile *)p; + acquire(); + return data; +} + +inline void OrderAccess::release_store(volatile jbyte* p, jbyte v) { release(); *p = v; } +inline void OrderAccess::release_store(volatile jshort* p, jshort v) { release(); *p = v; } +inline void OrderAccess::release_store(volatile jint* p, jint v) { release(); *p = v; } +inline void OrderAccess::release_store(volatile jlong* p, jlong v) +{ release(); os::atomic_copy64(&v, p); } +inline void OrderAccess::release_store(volatile jubyte* p, jubyte v) { release(); *p = v; } +inline void OrderAccess::release_store(volatile jushort* p, jushort v) { release(); *p = v; } +inline void OrderAccess::release_store(volatile juint* p, juint v) { release(); *p = v; } +inline void OrderAccess::release_store(volatile julong* p, julong v) +{ release(); os::atomic_copy64(&v, p); } +inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { release(); *p = v; } +inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) +{ release(); os::atomic_copy64(&v, p); } + +inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { release(); *p = v; } +inline void OrderAccess::release_store_ptr(volatile void* p, void* v) +{ release(); *(void* volatile *)p = v; } + +inline void OrderAccess::store_fence(jbyte* p, jbyte v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jshort* p, jshort v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jint* p, jint v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jlong* p, jlong v) { os::atomic_copy64(&v, p); fence(); } +inline void OrderAccess::store_fence(jubyte* p, jubyte v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jushort* p, jushort v) { *p = v; fence(); } +inline void OrderAccess::store_fence(juint* p, juint v) { *p = v; fence(); } +inline void OrderAccess::store_fence(julong* p, julong v) { os::atomic_copy64(&v, p); fence(); } +inline void OrderAccess::store_fence(jfloat* p, jfloat v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jdouble* p, jdouble v) { os::atomic_copy64(&v, p); fence(); } + +inline void OrderAccess::store_ptr_fence(intptr_t* p, intptr_t v) { *p = v; fence(); } +inline void OrderAccess::store_ptr_fence(void** p, void* v) { *p = v; fence(); } + +inline void OrderAccess::release_store_fence(volatile jbyte* p, jbyte v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jshort* p, jshort v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jint* p, jint v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jlong* p, jlong v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jubyte* p, jubyte v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jushort* p, jushort v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile juint* p, juint v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store(p, v); fence(); } + +inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) { release_store_ptr(p, v); fence(); } +inline void OrderAccess::release_store_ptr_fence(volatile void* p, void* v) { release_store_ptr(p, v); fence(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,467 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// do not include precompiled header file +#include "incls/_os_linux_zero.cpp.incl" + +address os::current_stack_pointer() +{ + address dummy = (address) &dummy; + return dummy; +} + +frame os::get_sender_for_C_frame(frame* fr) +{ + Unimplemented(); +} + +frame os::current_frame() +{ + Unimplemented(); +} + +char* os::non_memory_address_word() +{ + // Must never look like an address returned by reserve_memory, + // even in its subfields (as defined by the CPU immediate fields, + // if the CPU splits constants across multiple instructions). +#ifdef SPARC + // On SPARC, 0 != %hi(any real address), because there is no + // allocation in the first 1Kb of the virtual address space. + return (char *) 0; +#else + // This is the value for x86; works pretty well for PPC too. + return (char *) -1; +#endif // SPARC +} + +void os::initialize_thread() +{ + // Nothing to do. +} + +address os::Linux::ucontext_get_pc(ucontext_t* uc) +{ + Unimplemented(); +} + +ExtendedPC os::fetch_frame_from_context(void* ucVoid, + intptr_t** ret_sp, + intptr_t** ret_fp) { + Unimplemented(); +} + +frame os::fetch_frame_from_context(void* ucVoid) +{ + Unimplemented(); +} + +extern "C" int +JVM_handle_linux_signal(int sig, + siginfo_t* info, + void* ucVoid, + int abort_if_unrecognized) +{ + ucontext_t* uc = (ucontext_t*) ucVoid; + + Thread* t = ThreadLocalStorage::get_thread_slow(); + + SignalHandlerMark shm(t); + + // Note: it's not uncommon that JNI code uses signal/sigset to + // install then restore certain signal handler (e.g. to temporarily + // block SIGPIPE, or have a SIGILL handler when detecting CPU + // type). When that happens, JVM_handle_linux_signal() might be + // invoked with junk info/ucVoid. To avoid unnecessary crash when + // libjsig is not preloaded, try handle signals that do not require + // siginfo/ucontext first. + + if (sig == SIGPIPE || sig == SIGXFSZ) { + // allow chained handler to go first + if (os::Linux::chained_handler(sig, info, ucVoid)) { + return true; + } else { + if (PrintMiscellaneous && (WizardMode || Verbose)) { + char buf[64]; + warning("Ignoring %s - see bugs 4229104 or 646499219", + os::exception_name(sig, buf, sizeof(buf))); + } + return true; + } + } + + JavaThread* thread = NULL; + VMThread* vmthread = NULL; + if (os::Linux::signal_handlers_are_installed) { + if (t != NULL ){ + if(t->is_Java_thread()) { + thread = (JavaThread*)t; + } + else if(t->is_VM_thread()){ + vmthread = (VMThread *)t; + } + } + } + + if (info != NULL && thread != NULL) { + // Handle ALL stack overflow variations here + if (sig == SIGSEGV) { + address addr = (address) info->si_addr; + + // check if fault address is within thread stack + if (addr < thread->stack_base() && + addr >= thread->stack_base() - thread->stack_size()) { + // stack overflow + if (thread->in_stack_yellow_zone(addr)) { + thread->disable_stack_yellow_zone(); + Unimplemented(); + } + else if (thread->in_stack_red_zone(addr)) { + thread->disable_stack_red_zone(); + Unimplemented(); + } + else { + // Accessing stack address below sp may cause SEGV if + // current thread has MAP_GROWSDOWN stack. This should + // only happen when current thread was created by user + // code with MAP_GROWSDOWN flag and then attached to VM. + // See notes in os_linux.cpp. + if (thread->osthread()->expanding_stack() == 0) { + thread->osthread()->set_expanding_stack(); + if (os::Linux::manually_expand_stack(thread, addr)) { + thread->osthread()->clear_expanding_stack(); + return true; + } + thread->osthread()->clear_expanding_stack(); + } + else { + fatal("recursive segv. expanding stack."); + } + } + } + } + + /*if (thread->thread_state() == _thread_in_Java) { + Unimplemented(); + } + else*/ if (thread->thread_state() == _thread_in_vm && + sig == SIGBUS && thread->doing_unsafe_access()) { + Unimplemented(); + } + + // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC + // kicks in and the heap gets shrunk before the field access. + /*if (sig == SIGSEGV || sig == SIGBUS) { + address addr = JNI_FastGetField::find_slowcase_pc(pc); + if (addr != (address)-1) { + stub = addr; + } + }*/ + + // Check to see if we caught the safepoint code in the process + // of write protecting the memory serialization page. It write + // enables the page immediately after protecting it so we can + // just return to retry the write. + if (sig == SIGSEGV && + os::is_memory_serialize_page(thread, (address) info->si_addr)) { + // Block current thread until permission is restored. + os::block_on_serialize_page_trap(); + return true; + } + } + + // signal-chaining + if (os::Linux::chained_handler(sig, info, ucVoid)) { + return true; + } + + if (!abort_if_unrecognized) { + // caller wants another chance, so give it to him + return false; + } + +#ifndef PRODUCT + if (sig == SIGSEGV) { + fatal("\n#" + "\n# /--------------------\\" + "\n# | segmentation fault |" + "\n# \\---\\ /--------------/" + "\n# /" + "\n# [-] |\\_/| " + "\n# (+)=C |o o|__ " + "\n# | | =-*-=__\\ " + "\n# OOO c_c_(___)"); + } +#endif // !PRODUCT + + const char *fmt = "caught unhandled signal %d"; + char buf[64]; + + sprintf(buf, fmt, sig); + fatal(buf); +} + +void os::Linux::init_thread_fpu_state(void) +{ + // Nothing to do +} + +int os::Linux::get_fpu_control_word() +{ + Unimplemented(); +} + +void os::Linux::set_fpu_control_word(int fpu) +{ + Unimplemented(); +} + +bool os::is_allocatable(size_t bytes) +{ + Unimplemented(); +} + +/////////////////////////////////////////////////////////////////////////////// +// thread stack + +size_t os::Linux::min_stack_allowed = 64 * K; + +bool os::Linux::supports_variable_stack_size() +{ + return true; +} + +size_t os::Linux::default_stack_size(os::ThreadType thr_type) +{ +#ifdef _LP64 + size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); +#else + size_t s = (thr_type == os::compiler_thread ? 2 * M : 512 * K); +#endif // _LP64 + return s; +} + +size_t os::Linux::default_guard_size(os::ThreadType thr_type) +{ + // Only enable glibc guard pages for non-Java threads + // (Java threads have HotSpot guard pages) + return (thr_type == java_thread ? 0 : page_size()); +} + +static void current_stack_region(address *bottom, size_t *size) +{ + pthread_attr_t attr; + int res = pthread_getattr_np(pthread_self(), &attr); + if (res != 0) { + if (res == ENOMEM) { + vm_exit_out_of_memory(0, "pthread_getattr_np"); + } + else { + fatal1("pthread_getattr_np failed with errno = %d", res); + } + } + + address stack_bottom; + size_t stack_bytes; + res = pthread_attr_getstack(&attr, (void **) &stack_bottom, &stack_bytes); + if (res != 0) { + fatal1("pthread_attr_getstack failed with errno = %d", res); + } + address stack_top = stack_bottom + stack_bytes; + + // The block of memory returned by pthread_attr_getstack() includes + // guard pages where present. We need to trim these off. + size_t page_bytes = os::Linux::page_size(); + assert(((intptr_t) stack_bottom & (page_bytes - 1)) == 0, "unaligned stack"); + + size_t guard_bytes; + res = pthread_attr_getguardsize(&attr, &guard_bytes); + if (res != 0) { + fatal1("pthread_attr_getguardsize failed with errno = %d", res); + } + int guard_pages = align_size_up(guard_bytes, page_bytes) / page_bytes; + assert(guard_bytes == guard_pages * page_bytes, "unaligned guard"); + +#ifdef IA64 + // IA64 has two stacks sharing the same area of memory, a normal + // stack growing downwards and a register stack growing upwards. + // Guard pages, if present, are in the centre. This code splits + // the stack in two even without guard pages, though in theory + // there's nothing to stop us allocating more to the normal stack + // or more to the register stack if one or the other were found + // to grow faster. + int total_pages = align_size_down(stack_bytes, page_bytes) / page_bytes; + stack_bottom += (total_pages - guard_pages) / 2 * page_bytes; +#endif // IA64 + + stack_bottom += guard_bytes; + + pthread_attr_destroy(&attr); + + // The initial thread has a growable stack, and the size reported + // by pthread_attr_getstack is the maximum size it could possibly + // be given what currently mapped. This can be huge, so we cap it. + if (os::Linux::is_initial_thread()) { + stack_bytes = stack_top - stack_bottom; + + if (stack_bytes > JavaThread::stack_size_at_create()) + stack_bytes = JavaThread::stack_size_at_create(); + + stack_bottom = stack_top - stack_bytes; + } + + assert(os::current_stack_pointer() >= stack_bottom, "should do"); + assert(os::current_stack_pointer() < stack_top, "should do"); + + *bottom = stack_bottom; + *size = stack_top - stack_bottom; +} + +address os::current_stack_base() +{ + address bottom; + size_t size; + current_stack_region(&bottom, &size); + return bottom + size; +} + +size_t os::current_stack_size() +{ + // stack size includes normal stack and HotSpot guard pages + address bottom; + size_t size; + current_stack_region(&bottom, &size); + return size; +} + +///////////////////////////////////////////////////////////////////////////// +// helper functions for fatal error handler + +void os::print_context(outputStream* st, void* context) +{ + Unimplemented(); +} + +///////////////////////////////////////////////////////////////////////////// +// Stubs for things that would be in linux_zero.s if it existed. +// You probably want to disassemble these monkeys to check they're ok. + +extern "C" { + int SpinPause() + { + } + + int SafeFetch32(int *adr, int errValue) + { + int value = errValue; + value = *adr; + return value; + } + intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) + { + intptr_t value = errValue; + value = *adr; + return value; + } + + void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) + { + if (from > to) { + jshort *end = from + count; + while (from < end) + *(to++) = *(from++); + } + else if (from < to) { + jshort *end = from; + from += count - 1; + to += count - 1; + while (from >= end) + *(to--) = *(from--); + } + } + void _Copy_conjoint_jints_atomic(jint* from, jint* to, size_t count) + { + if (from > to) { + jint *end = from + count; + while (from < end) + *(to++) = *(from++); + } + else if (from < to) { + jint *end = from; + from += count - 1; + to += count - 1; + while (from >= end) + *(to--) = *(from--); + } + } + void _Copy_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) + { + if (from > to) { + jlong *end = from + count; + while (from < end) + os::atomic_copy64(from++, to++); + } + else if (from < to) { + jlong *end = from; + from += count - 1; + to += count - 1; + while (from >= end) + os::atomic_copy64(from--, to--); + } + } + + void _Copy_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) + { + Unimplemented(); + } + void _Copy_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, + size_t count) { + Unimplemented(); + } + void _Copy_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) + { + Unimplemented(); + } + void _Copy_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, + size_t count) { + Unimplemented(); + } +}; + +///////////////////////////////////////////////////////////////////////////// +// Implementations of atomic operations not supported by processors. +// -- http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Atomic-Builtins.html + +#ifndef _LP64 +extern "C" { + long long unsigned int __sync_val_compare_and_swap_8( + volatile void *ptr, + long long unsigned int oldval, + long long unsigned int newval) + { + Unimplemented(); + } +}; +#endif // !_LP64
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/os_linux_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,46 @@ +/* + * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + static void setup_fpu() {} + + static bool is_allocatable(size_t bytes); + + // Used to register dynamic code cache area with the OS + // Note: Currently only used in 64 bit Windows implementations + static bool register_code_area(char *low, char *high) { return true; } + + // Atomically copy 64 bits of data + static void atomic_copy64(volatile void *src, volatile void *dst) + { +#if defined(PPC) && !defined(_LP64) + double tmp; + asm volatile ("lfd %0, 0(%1)\n" + "stfd %0, 0(%2)\n" + : "=f"(tmp) + : "b"(src), "b"(dst)); +#else + *(jlong *) dst = *(jlong *) src; +#endif // PPC && !_LP64 + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/prefetch_linux_zero.inline.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +inline void Prefetch::read(void* loc, intx interval) +{ +} + +inline void Prefetch::write(void* loc, intx interval) +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,42 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_threadLS_linux_zero.cpp.incl" + +void ThreadLocalStorage::generate_code_for_get_thread() +{ + // nothing to do +} + +void ThreadLocalStorage::pd_init() +{ + // nothing to do +} + +void ThreadLocalStorage::pd_set_thread(Thread* thread) +{ + os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/threadLS_linux_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// Processor dependent parts of ThreadLocalStorage + +public: + + static Thread* thread() + { + return (Thread*) os::thread_local_storage_at(thread_index()); + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,118 @@ +/* + * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007, 2008, 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + private: + ZeroStack _zero_stack; + ZeroFrame* _top_zero_frame; + + void pd_initialize() + { + _top_zero_frame = NULL; + } + + public: + ZeroStack *zero_stack() + { + return &_zero_stack; + } + + public: + ZeroFrame *top_zero_frame() + { + return _top_zero_frame; + } + void push_zero_frame(ZeroFrame *frame) + { + *(ZeroFrame **) frame = _top_zero_frame; + _top_zero_frame = frame; + } + void pop_zero_frame() + { + _zero_stack.set_sp((intptr_t *) _top_zero_frame + 1); + _top_zero_frame = *(ZeroFrame **) _top_zero_frame; + } + + public: + static ByteSize zero_stack_offset() + { + return byte_offset_of(JavaThread, _zero_stack); + } + static ByteSize top_zero_frame_offset() + { + return byte_offset_of(JavaThread, _top_zero_frame); + } + + public: + void record_base_of_stack_pointer() + { + assert(top_zero_frame() == NULL, "junk on stack prior to Java call"); + } + void set_base_of_stack_pointer(intptr_t* base_sp) + { + assert(base_sp == NULL, "should be"); + assert(top_zero_frame() == NULL, "junk on stack after Java call"); + } + + public: + void set_last_Java_frame() + { + JavaFrameAnchor *jfa = frame_anchor(); + jfa->set_last_Java_sp((intptr_t *) top_zero_frame()); + } + void reset_last_Java_frame() + { + JavaFrameAnchor *jfa = frame_anchor(); + jfa->set_last_Java_sp(NULL); + } + + private: + frame pd_last_frame() + { + assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); + return frame(last_Java_sp()); + } + + public: + // Check for pending suspend requests and pending asynchronous + // exceptions. There are separate accessors for these, but + // _suspend_flags is volatile so using them would be unsafe. + bool has_special_condition_for_native_trans() + { + return _suspend_flags != 0; + } + + public: + bool pd_get_top_frame_for_signal_handler(frame* fr_addr, + void* ucontext, + bool isInJava) + { + Unimplemented(); + } + + // These routines are only used on cpu architectures that + // have separate register stacks (Itanium). + static bool register_stack_overflow() { return false; } + static void enable_register_stack_guard() {} + static void disable_register_stack_guard() {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,45 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// These are the OS and CPU-specific fields, types and integer +// constants required by the Serviceability Agent. This file is +// referenced by vmStructs.cpp. + +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ + /* This must be the last entry, and must be present */ \ + last_entry() + + +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ + /* This must be the last entry, and must be present */ \ + last_entry() + +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ + /* This must be the last entry, and must be present */ \ + last_entry() + +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ + /* This must be the last entry, and must be present */ \ + last_entry()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os_cpu/linux_zero/vm/vm_version_linux_zero.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,24 @@ +/* + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */
--- a/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -3031,9 +3031,9 @@ tty->print_cr("&native_fresult: " INTPTR_FORMAT, (uintptr_t) &this->_native_fresult); tty->print_cr("native_lresult: " INTPTR_FORMAT, (uintptr_t) this->_native_lresult); #endif -#ifdef IA64 +#if defined(IA64) && !defined(ZERO) tty->print_cr("last_Java_fp: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_fp); -#endif // IA64 +#endif // IA64 && !ZERO tty->print_cr("self_link: " INTPTR_FORMAT, (uintptr_t) this->_self_link); }
--- a/src/share/vm/interpreter/oopMapCache.cpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/interpreter/oopMapCache.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -281,7 +281,7 @@ public: void pass_int() { /* ignore */ } void pass_long() { /* ignore */ } -#ifdef _LP64 +#if defined(_LP64) || defined(ZERO) void pass_float() { /* ignore */ } #endif void pass_double() { /* ignore */ }
--- a/src/share/vm/opto/block.cpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/opto/block.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -357,6 +357,9 @@ #ifndef PRODUCT , _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining")) #endif +#ifdef ASSERT + , _raw_oops(a) +#endif { ResourceMark rm; // I'll need a few machine-specific GotoNodes. Make an Ideal GotoNode,
--- a/src/share/vm/opto/block.hpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/opto/block.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -380,6 +380,10 @@ bool _trace_opto_pipelining; // tracing flag #endif +#ifdef ASSERT + Unique_Node_List _raw_oops; +#endif + // Build dominators void Dominators();
--- a/src/share/vm/opto/buildOopMap.cpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/opto/buildOopMap.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -74,9 +74,11 @@ // this block. Block *_b; // Block for this struct OopFlow *_next; // Next free OopFlow + // or NULL if dead/conflict + Compile* C; - OopFlow( short *callees, Node **defs ) : _callees(callees), _defs(defs), - _b(NULL), _next(NULL) { } + OopFlow( short *callees, Node **defs, Compile* c ) : _callees(callees), _defs(defs), + _b(NULL), _next(NULL), C(c) { } // Given reaching-defs for this block start, compute it for this block end void compute_reach( PhaseRegAlloc *regalloc, int max_reg, Dict *safehash ); @@ -88,7 +90,7 @@ void clone( OopFlow *flow, int max_size); // Make a new OopFlow from scratch - static OopFlow *make( Arena *A, int max_size ); + static OopFlow *make( Arena *A, int max_size, Compile* C ); // Build an oopmap from the current flow info OopMap *build_oop_map( Node *n, int max_reg, PhaseRegAlloc *regalloc, int* live ); @@ -180,11 +182,11 @@ } //------------------------------make------------------------------------------- -OopFlow *OopFlow::make( Arena *A, int max_size ) { +OopFlow *OopFlow::make( Arena *A, int max_size, Compile* C ) { short *callees = NEW_ARENA_ARRAY(A,short,max_size+1); Node **defs = NEW_ARENA_ARRAY(A,Node*,max_size+1); debug_only( memset(defs,0,(max_size+1)*sizeof(Node*)) ); - OopFlow *flow = new (A) OopFlow(callees+1, defs+1); + OopFlow *flow = new (A) OopFlow(callees+1, defs+1, C); assert( &flow->_callees[OptoReg::Bad] == callees, "Ok to index at OptoReg::Bad" ); assert( &flow->_defs [OptoReg::Bad] == defs , "Ok to index at OptoReg::Bad" ); return flow; @@ -288,7 +290,7 @@ m = m->in(idx); } } - guarantee( 0, "must find derived/base pair" ); + guarantee( 0, "must find derived/base pair" ); } found: ; Node *base = n->in(i+1); // Base is other half of pair @@ -347,6 +349,13 @@ } else { // Other - some reaching non-oop value omap->set_value( r); +#ifdef ASSERT + if( t->isa_rawptr() && C->cfg()->_raw_oops.member(def) ) { + def->dump(); + n->dump(); + assert(false, "there should be a oop in OopMap instead of a live raw oop at safepoint"); + } +#endif } } @@ -562,7 +571,7 @@ // Do the first block 'by hand' to prime the worklist Block *entry = _cfg->_blocks[1]; - OopFlow *rootflow = OopFlow::make(A,max_reg); + OopFlow *rootflow = OopFlow::make(A,max_reg,this); // Initialize to 'bottom' (not 'top') memset( rootflow->_callees, OptoReg::Bad, max_reg*sizeof(short) ); memset( rootflow->_defs , 0, max_reg*sizeof(Node*) ); @@ -628,7 +637,7 @@ // Carry it forward. } else { // Draw a new OopFlow from the freelist if( !free_list ) - free_list = OopFlow::make(A,max_reg); + free_list = OopFlow::make(A,max_reg,C); flow = free_list; assert( flow->_b == NULL, "oopFlow is not free" ); free_list = flow->_next;
--- a/src/share/vm/opto/gcm.cpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/opto/gcm.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -1130,6 +1130,9 @@ Node *def = self->in(1); if (def != NULL && def->bottom_type()->base() == Type::RawPtr) { early->add_inst(self); +#ifdef ASSERT + _raw_oops.push(def); +#endif continue; } break;
--- a/src/share/vm/opto/library_call.cpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/opto/library_call.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -165,6 +165,7 @@ bool inline_native_getLength(); bool inline_array_copyOf(bool is_copyOfRange); bool inline_array_equals(); + void copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark); bool inline_native_clone(bool is_virtual); bool inline_native_Reflection_getCallerClass(); bool inline_native_AtomicLong_get(); @@ -181,7 +182,6 @@ Node* src, Node* src_offset, Node* dest, Node* dest_offset, Node* copy_length, - int nargs, // arguments on stack for debug info bool disjoint_bases = false, bool length_never_negative = false, RegionNode* slow_region = NULL); @@ -202,17 +202,16 @@ void generate_slow_arraycopy(const TypePtr* adr_type, Node* src, Node* src_offset, Node* dest, Node* dest_offset, - Node* copy_length, - int nargs); + Node* copy_length); Node* generate_checkcast_arraycopy(const TypePtr* adr_type, Node* dest_elem_klass, Node* src, Node* src_offset, Node* dest, Node* dest_offset, - Node* copy_length, int nargs); + Node* copy_length); Node* generate_generic_arraycopy(const TypePtr* adr_type, Node* src, Node* src_offset, Node* dest, Node* dest_offset, - Node* copy_length, int nargs); + Node* copy_length); void generate_unchecked_arraycopy(const TypePtr* adr_type, BasicType basic_elem_type, bool disjoint_bases, @@ -3230,7 +3229,8 @@ Node* orig_tail = _gvn.transform( new(C, 3) SubINode(orig_length, start) ); Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length); - Node* newcopy = new_array(klass_node, length, nargs); + const bool raw_mem_only = true; + Node* newcopy = new_array(klass_node, length, nargs, raw_mem_only); // Generate a direct call to the right arraycopy function(s). // We know the copy is disjoint but we might not know if the @@ -3241,7 +3241,7 @@ bool length_never_negative = true; generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT, original, start, newcopy, intcon(0), moved, - nargs, disjoint_bases, length_never_negative); + disjoint_bases, length_never_negative); push(newcopy); } @@ -3883,6 +3883,98 @@ return true; } +//------------------------clone_coping----------------------------------- +// Helper function for inline_native_clone. +void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark) { + assert(obj_size != NULL, ""); + Node* raw_obj = alloc_obj->in(1); + assert(alloc_obj->is_CheckCastPP() && raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), ""); + + if (ReduceBulkZeroing) { + // We will be completely responsible for initializing this object - + // mark Initialize node as complete. + AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn); + // The object was just allocated - there should be no any stores! + guarantee(alloc != NULL && alloc->maybe_set_complete(&_gvn), ""); + } + + // Cast to Object for arraycopy. + // We can't use the original CheckCastPP since it should be moved + // after the arraycopy to prevent stores flowing above it. + Node* new_obj = new(C, 2) CheckCastPPNode(alloc_obj->in(0), raw_obj, + TypeInstPtr::NOTNULL); + new_obj = _gvn.transform(new_obj); + // Substitute in the locally valid dest_oop. + replace_in_map(alloc_obj, new_obj); + + // Copy the fastest available way. + // TODO: generate fields copies for small objects instead. + Node* src = obj; + Node* dest = new_obj; + Node* size = _gvn.transform(obj_size); + + // Exclude the header but include array length to copy by 8 bytes words. + // Can't use base_offset_in_bytes(bt) since basic type is unknown. + int base_off = is_array ? arrayOopDesc::length_offset_in_bytes() : + instanceOopDesc::base_offset_in_bytes(); + // base_off: + // 8 - 32-bit VM + // 12 - 64-bit VM, compressed oops + // 16 - 64-bit VM, normal oops + if (base_off % BytesPerLong != 0) { + assert(UseCompressedOops, ""); + if (is_array) { + // Exclude length to copy by 8 bytes words. + base_off += sizeof(int); + } else { + // Include klass to copy by 8 bytes words. + base_off = instanceOopDesc::klass_offset_in_bytes(); + } + assert(base_off % BytesPerLong == 0, "expect 8 bytes alignment"); + } + src = basic_plus_adr(src, base_off); + dest = basic_plus_adr(dest, base_off); + + // Compute the length also, if needed: + Node* countx = size; + countx = _gvn.transform( new (C, 3) SubXNode(countx, MakeConX(base_off)) ); + countx = _gvn.transform( new (C, 3) URShiftXNode(countx, intcon(LogBytesPerLong) )); + + const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; + bool disjoint_bases = true; + generate_unchecked_arraycopy(raw_adr_type, T_LONG, disjoint_bases, + src, NULL, dest, NULL, countx); + + // If necessary, emit some card marks afterwards. (Non-arrays only.) + if (card_mark) { + assert(!is_array, ""); + // Put in store barrier for any and all oops we are sticking + // into this object. (We could avoid this if we could prove + // that the object type contains no oop fields at all.) + Node* no_particular_value = NULL; + Node* no_particular_field = NULL; + int raw_adr_idx = Compile::AliasIdxRaw; + post_barrier(control(), + memory(raw_adr_type), + new_obj, + no_particular_field, + raw_adr_idx, + no_particular_value, + T_OBJECT, + false); + } + + // Move the original CheckCastPP after arraycopy. + _gvn.hash_delete(alloc_obj); + alloc_obj->set_req(0, control()); + // Replace raw memory edge with new CheckCastPP to have a live oop + // at safepoints instead of raw value. + assert(new_obj->is_CheckCastPP() && new_obj->in(1) == alloc_obj->in(1), "sanity"); + alloc_obj->set_req(1, new_obj); // cast to the original type + _gvn.hash_find_insert(alloc_obj); // put back into GVN table + // Restore in the locally valid dest_oop. + replace_in_map(new_obj, alloc_obj); +} //------------------------inline_native_clone---------------------------- // Here are the simple edge cases: @@ -3917,8 +4009,9 @@ // paths into result_reg: enum { _slow_path = 1, // out-of-line call to clone method (virtual or not) - _objArray_path, // plain allocation, plus arrayof_oop_arraycopy - _fast_path, // plain allocation, plus a CopyArray operation + _objArray_path, // plain array allocation, plus arrayof_oop_arraycopy + _array_path, // plain array allocation, plus arrayof_long_arraycopy + _instance_path, // plain instance allocation, plus arrayof_long_arraycopy PATH_LIMIT }; RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); @@ -3933,18 +4026,6 @@ int raw_adr_idx = Compile::AliasIdxRaw; const bool raw_mem_only = true; - // paths into alloc_reg (on the fast path, just before the CopyArray): - enum { _typeArray_alloc = 1, _instance_alloc, ALLOC_LIMIT }; - RegionNode* alloc_reg = new(C, ALLOC_LIMIT) RegionNode(ALLOC_LIMIT); - PhiNode* alloc_val = new(C, ALLOC_LIMIT) PhiNode(alloc_reg, raw_adr_type); - PhiNode* alloc_siz = new(C, ALLOC_LIMIT) PhiNode(alloc_reg, TypeX_X); - PhiNode* alloc_i_o = new(C, ALLOC_LIMIT) PhiNode(alloc_reg, Type::ABIO); - PhiNode* alloc_mem = new(C, ALLOC_LIMIT) PhiNode(alloc_reg, Type::MEMORY, - raw_adr_type); - record_for_igvn(alloc_reg); - - bool card_mark = false; // (see below) - Node* array_ctl = generate_array_guard(obj_klass, (RegionNode*)NULL); if (array_ctl != NULL) { // It's an array. @@ -3954,16 +4035,6 @@ Node* obj_size = NULL; Node* alloc_obj = new_array(obj_klass, obj_length, nargs, raw_mem_only, &obj_size); - assert(obj_size != NULL, ""); - Node* raw_obj = alloc_obj->in(1); - assert(raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), ""); - if (ReduceBulkZeroing) { - AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn); - if (alloc != NULL) { - // We will be completely responsible for initializing this object. - alloc->maybe_set_complete(&_gvn); - } - } if (!use_ReduceInitialCardMarks()) { // If it is an oop array, it requires very special treatment, @@ -3977,7 +4048,7 @@ bool length_never_negative = true; generate_arraycopy(TypeAryPtr::OOPS, T_OBJECT, obj, intcon(0), alloc_obj, intcon(0), - obj_length, nargs, + obj_length, disjoint_bases, length_never_negative); result_reg->init_req(_objArray_path, control()); result_val->init_req(_objArray_path, alloc_obj); @@ -3992,19 +4063,24 @@ // the object. // Otherwise, there are no card marks to worry about. - alloc_val->init_req(_typeArray_alloc, raw_obj); - alloc_siz->init_req(_typeArray_alloc, obj_size); - alloc_reg->init_req(_typeArray_alloc, control()); - alloc_i_o->init_req(_typeArray_alloc, i_o()); - alloc_mem->init_req(_typeArray_alloc, memory(raw_adr_type)); + + if (!stopped()) { + copy_to_clone(obj, alloc_obj, obj_size, true, false); + + // Present the results of the copy. + result_reg->init_req(_array_path, control()); + result_val->init_req(_array_path, alloc_obj); + result_i_o ->set_req(_array_path, i_o()); + result_mem ->set_req(_array_path, reset_memory()); + } } - // We only go to the fast case code if we pass a number of guards. + // We only go to the instance fast case code if we pass a number of guards. // The paths which do not pass are accumulated in the slow_region. RegionNode* slow_region = new (C, 1) RegionNode(1); record_for_igvn(slow_region); if (!stopped()) { - // It's an instance. Make the slow-path tests. + // It's an instance (we did array above). Make the slow-path tests. // If this is a virtual call, we generate a funny guard. We grab // the vtable entry corresponding to clone() from the target object. // If the target method which we are calling happens to be the @@ -4031,25 +4107,14 @@ PreserveJVMState pjvms(this); Node* obj_size = NULL; Node* alloc_obj = new_instance(obj_klass, NULL, raw_mem_only, &obj_size); - assert(obj_size != NULL, ""); - Node* raw_obj = alloc_obj->in(1); - assert(raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), ""); - if (ReduceBulkZeroing) { - AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn); - if (alloc != NULL && !alloc->maybe_set_complete(&_gvn)) - alloc = NULL; - } - if (!use_ReduceInitialCardMarks()) { - // Put in store barrier for any and all oops we are sticking - // into this object. (We could avoid this if we could prove - // that the object type contains no oop fields at all.) - card_mark = true; - } - alloc_val->init_req(_instance_alloc, raw_obj); - alloc_siz->init_req(_instance_alloc, obj_size); - alloc_reg->init_req(_instance_alloc, control()); - alloc_i_o->init_req(_instance_alloc, i_o()); - alloc_mem->init_req(_instance_alloc, memory(raw_adr_type)); + + copy_to_clone(obj, alloc_obj, obj_size, false, !use_ReduceInitialCardMarks()); + + // Present the results of the slow call. + result_reg->init_req(_instance_path, control()); + result_val->init_req(_instance_path, alloc_obj); + result_i_o ->set_req(_instance_path, i_o()); + result_mem ->set_req(_instance_path, reset_memory()); } // Generate code for the slow case. We make a call to clone(). @@ -4065,82 +4130,12 @@ result_mem ->set_req(_slow_path, reset_memory()); } - // The object is allocated, as an array and/or an instance. Now copy it. - set_control( _gvn.transform(alloc_reg) ); - set_i_o( _gvn.transform(alloc_i_o) ); - set_memory( _gvn.transform(alloc_mem), raw_adr_type ); - Node* raw_obj = _gvn.transform(alloc_val); - - if (!stopped()) { - // Copy the fastest available way. - // (No need for PreserveJVMState, since we're using it all up now.) - // TODO: generate fields/elements copies for small objects instead. - Node* src = obj; - Node* dest = raw_obj; - Node* size = _gvn.transform(alloc_siz); - - // Exclude the header. - int base_off = instanceOopDesc::base_offset_in_bytes(); - if (UseCompressedOops) { - assert(base_off % BytesPerLong != 0, "base with compressed oops"); - // With compressed oops base_offset_in_bytes is 12 which creates - // the gap since countx is rounded by 8 bytes below. - // Copy klass and the gap. - base_off = instanceOopDesc::klass_offset_in_bytes(); - } - src = basic_plus_adr(src, base_off); - dest = basic_plus_adr(dest, base_off); - - // Compute the length also, if needed: - Node* countx = size; - countx = _gvn.transform( new (C, 3) SubXNode(countx, MakeConX(base_off)) ); - countx = _gvn.transform( new (C, 3) URShiftXNode(countx, intcon(LogBytesPerLong) )); - - // Select an appropriate instruction to initialize the range. - // The CopyArray instruction (if supported) can be optimized - // into a discrete set of scalar loads and stores. - bool disjoint_bases = true; - generate_unchecked_arraycopy(raw_adr_type, T_LONG, disjoint_bases, - src, NULL, dest, NULL, countx); - - // Now that the object is properly initialized, type it as an oop. - // Use a secondary InitializeNode memory barrier. - InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, raw_adr_idx, - raw_obj)->as_Initialize(); - init->set_complete(&_gvn); // (there is no corresponding AllocateNode) - Node* new_obj = new(C, 2) CheckCastPPNode(control(), raw_obj, - TypeInstPtr::NOTNULL); - new_obj = _gvn.transform(new_obj); - - // If necessary, emit some card marks afterwards. (Non-arrays only.) - if (card_mark) { - Node* no_particular_value = NULL; - Node* no_particular_field = NULL; - post_barrier(control(), - memory(raw_adr_type), - new_obj, - no_particular_field, - raw_adr_idx, - no_particular_value, - T_OBJECT, - false); - } - // Present the results of the slow call. - result_reg->init_req(_fast_path, control()); - result_val->init_req(_fast_path, new_obj); - result_i_o ->set_req(_fast_path, i_o()); - result_mem ->set_req(_fast_path, reset_memory()); - } - // Return the combined state. set_control( _gvn.transform(result_reg) ); set_i_o( _gvn.transform(result_i_o) ); set_all_memory( _gvn.transform(result_mem) ); - // Cast the result to a sharper type, since we know what clone does. - Node* new_obj = _gvn.transform(result_val); - Node* cast = new (C, 2) CheckCastPPNode(control(), new_obj, toop); - push(_gvn.transform(cast)); + push(_gvn.transform(result_val)); return true; } @@ -4279,8 +4274,7 @@ // Call StubRoutines::generic_arraycopy stub. generate_arraycopy(TypeRawPtr::BOTTOM, T_CONFLICT, - src, src_offset, dest, dest_offset, length, - nargs); + src, src_offset, dest, dest_offset, length); // Do not let reads from the destination float above the arraycopy. // Since we cannot type the arrays, we don't know which slices @@ -4303,8 +4297,7 @@ // The component types are not the same or are not recognized. Punt. // (But, avoid the native method wrapper to JVM_ArrayCopy.) generate_slow_arraycopy(TypePtr::BOTTOM, - src, src_offset, dest, dest_offset, length, - nargs); + src, src_offset, dest, dest_offset, length); return true; } @@ -4361,7 +4354,7 @@ const TypePtr* adr_type = TypeAryPtr::get_array_body_type(dest_elem); generate_arraycopy(adr_type, dest_elem, src, src_offset, dest, dest_offset, length, - nargs, false, false, slow_region); + false, false, slow_region); return true; } @@ -4406,7 +4399,6 @@ Node* src, Node* src_offset, Node* dest, Node* dest_offset, Node* copy_length, - int nargs, bool disjoint_bases, bool length_never_negative, RegionNode* slow_region) { @@ -4418,7 +4410,6 @@ Node* original_dest = dest; AllocateArrayNode* alloc = NULL; // used for zeroing, if needed - Node* raw_dest = NULL; // used before zeroing, if needed bool must_clear_dest = false; // See if this is the initialization of a newly-allocated array. @@ -4437,15 +4428,18 @@ // "You break it, you buy it." InitializeNode* init = alloc->initialization(); assert(init->is_complete(), "we just did this"); - assert(dest->Opcode() == Op_CheckCastPP, "sanity"); + assert(dest->is_CheckCastPP(), "sanity"); assert(dest->in(0)->in(0) == init, "dest pinned"); - raw_dest = dest->in(1); // grab the raw pointer! - original_dest = dest; - dest = raw_dest; + + // Cast to Object for arraycopy. + // We can't use the original CheckCastPP since it should be moved + // after the arraycopy to prevent stores flowing above it. + Node* new_obj = new(C, 2) CheckCastPPNode(dest->in(0), dest->in(1), + TypeInstPtr::NOTNULL); + dest = _gvn.transform(new_obj); + // Substitute in the locally valid dest_oop. + replace_in_map(original_dest, dest); adr_type = TypeRawPtr::BOTTOM; // all initializations are into raw memory - // Decouple the original InitializeNode, turning it into a simple membar. - // We will build a new one at the end of this routine. - init->set_req(InitializeNode::RawAddress, top()); // From this point on, every exit path is responsible for // initializing any non-copied parts of the object to zero. must_clear_dest = true; @@ -4488,7 +4482,7 @@ assert(!must_clear_dest, ""); Node* cv = generate_generic_arraycopy(adr_type, src, src_offset, dest, dest_offset, - copy_length, nargs); + copy_length); if (cv == NULL) cv = intcon(-1); // failure (no stub available) checked_control = control(); checked_i_o = i_o(); @@ -4507,16 +4501,24 @@ generate_negative_guard(copy_length, slow_region); } + // copy_length is 0. if (!stopped() && must_clear_dest) { Node* dest_length = alloc->in(AllocateNode::ALength); if (_gvn.eqv_uncast(copy_length, dest_length) || _gvn.find_int_con(dest_length, 1) <= 0) { - // There is no zeroing to do. + // There is no zeroing to do. No need for a secondary raw memory barrier. } else { // Clear the whole thing since there are no source elements to copy. generate_clear_array(adr_type, dest, basic_elem_type, intcon(0), NULL, alloc->in(AllocateNode::AllocSize)); + // Use a secondary InitializeNode as raw memory barrier. + // Currently it is needed only on this path since other + // paths have stub or runtime calls as raw memory barriers. + InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, + Compile::AliasIdxRaw, + top())->as_Initialize(); + init->set_complete(&_gvn); // (there is no corresponding AllocateNode) } } @@ -4638,8 +4640,7 @@ Node* cv = generate_checkcast_arraycopy(adr_type, dest_elem_klass, src, src_offset, dest, dest_offset, - copy_length, - nargs); + copy_length); if (cv == NULL) cv = intcon(-1); // failure (no stub available) checked_control = control(); checked_i_o = i_o(); @@ -4701,8 +4702,8 @@ slow_i_o2 ->init_req(1, slow_i_o); slow_mem2 ->init_req(1, slow_mem); slow_reg2 ->init_req(2, control()); - slow_i_o2 ->init_req(2, i_o()); - slow_mem2 ->init_req(2, memory(adr_type)); + slow_i_o2 ->init_req(2, checked_i_o); + slow_mem2 ->init_req(2, checked_mem); slow_control = _gvn.transform(slow_reg2); slow_i_o = _gvn.transform(slow_i_o2); @@ -4747,21 +4748,9 @@ alloc->in(AllocateNode::AllocSize)); } - if (dest != original_dest) { - // Promote from rawptr to oop, so it looks right in the call's GC map. - dest = _gvn.transform( new(C,2) CheckCastPPNode(control(), dest, - TypeInstPtr::NOTNULL) ); - - // Edit the call's debug-info to avoid referring to original_dest. - // (The problem with original_dest is that it isn't ready until - // after the InitializeNode completes, but this stuff is before.) - // Substitute in the locally valid dest_oop. - replace_in_map(original_dest, dest); - } - generate_slow_arraycopy(adr_type, src, src_offset, dest, dest_offset, - copy_length, nargs); + copy_length); result_region->init_req(slow_call_path, control()); result_i_o ->init_req(slow_call_path, i_o()); @@ -4781,16 +4770,16 @@ if (dest != original_dest) { // Pin the "finished" array node after the arraycopy/zeroing operations. - // Use a secondary InitializeNode memory barrier. - InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, - Compile::AliasIdxRaw, - raw_dest)->as_Initialize(); - init->set_complete(&_gvn); // (there is no corresponding AllocateNode) _gvn.hash_delete(original_dest); original_dest->set_req(0, control()); + // Replace raw memory edge with new CheckCastPP to have a live oop + // at safepoints instead of raw value. + assert(dest->is_CheckCastPP() && dest->in(1) == original_dest->in(1), "sanity"); + original_dest->set_req(1, dest); // cast to the original type _gvn.hash_find_insert(original_dest); // put back into GVN table + // Restore in the locally valid dest_oop. + replace_in_map(dest, original_dest); } - // The memory edges above are precise in order to model effects around // array copies accurately to allow value numbering of field loads around // arraycopy. Such field loads, both before and after, are common in Java @@ -5074,16 +5063,13 @@ LibraryCallKit::generate_slow_arraycopy(const TypePtr* adr_type, Node* src, Node* src_offset, Node* dest, Node* dest_offset, - Node* copy_length, - int nargs) { - _sp += nargs; // any deopt will start just before call to enclosing method + Node* copy_length) { Node* call = make_runtime_call(RC_NO_LEAF | RC_UNCOMMON, OptoRuntime::slow_arraycopy_Type(), OptoRuntime::slow_arraycopy_Java(), "slow_arraycopy", adr_type, src, src_offset, dest, dest_offset, copy_length); - _sp -= nargs; // Handle exceptions thrown by this fellow: make_slow_call_ex(call, env()->Throwable_klass(), false); @@ -5095,8 +5081,7 @@ Node* dest_elem_klass, Node* src, Node* src_offset, Node* dest, Node* dest_offset, - Node* copy_length, - int nargs) { + Node* copy_length) { if (stopped()) return NULL; address copyfunc_addr = StubRoutines::checkcast_arraycopy(); @@ -5137,8 +5122,7 @@ LibraryCallKit::generate_generic_arraycopy(const TypePtr* adr_type, Node* src, Node* src_offset, Node* dest, Node* dest_offset, - Node* copy_length, - int nargs) { + Node* copy_length) { if (stopped()) return NULL; address copyfunc_addr = StubRoutines::generic_arraycopy();
--- a/src/share/vm/opto/loopopts.cpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/opto/loopopts.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -667,7 +667,6 @@ } } -#ifdef _LP64 static bool merge_point_safe(Node* region) { // 4799512: Stop split_if_with_blocks from splitting a block with a ConvI2LNode // having a PhiNode input. This sidesteps the dangerous case where the split @@ -676,20 +675,25 @@ // uses. // A better fix for this problem can be found in the BugTraq entry, but // expediency for Mantis demands this hack. + // 6855164: If the merge point has a FastLockNode with a PhiNode input, we stop + // split_if_with_blocks from splitting a block because we could not move around + // the FastLockNode. for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { Node* n = region->fast_out(i); if (n->is_Phi()) { for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { Node* m = n->fast_out(j); - if (m->Opcode() == Op_ConvI2L) { + if (m->is_FastLock()) return false; - } +#ifdef _LP64 + if (m->Opcode() == Op_ConvI2L) + return false; +#endif } } } return true; } -#endif //------------------------------place_near_use--------------------------------- @@ -771,12 +775,10 @@ if( get_loop(n_ctrl->in(j)) != n_loop ) return; -#ifdef _LP64 // Check for safety of the merge point. if( !merge_point_safe(n_ctrl) ) { return; } -#endif // Split compare 'n' through the merge point if it is profitable Node *phi = split_thru_phi( n, n_ctrl, policy );
--- a/src/share/vm/runtime/globals.hpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/runtime/globals.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -47,7 +47,6 @@ define_pd_global(intx, OnStackReplacePercentage, 0); define_pd_global(bool, ResizeTLAB, false); define_pd_global(intx, FreqInlineSize, 0); -define_pd_global(intx, InlineSmallCode, 0); define_pd_global(intx, NewSizeThreadIncrease, 4*K); define_pd_global(intx, NewRatio, 4); define_pd_global(intx, InlineClassNatives, true);
--- a/src/share/vm/runtime/icache.cpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/runtime/icache.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -78,6 +78,7 @@ } void AbstractICache::invalidate_range(address start, int nbytes) { +#ifndef ZERO static bool firstTime = true; if (firstTime) { guarantee(start == CAST_FROM_FN_PTR(address, _flush_icache_stub), @@ -97,6 +98,7 @@ } call_flush_stub(start, round_to(nbytes, ICache::line_size) >> ICache::log2_line_size); +#endif // ZERO } // For init.cpp
--- a/src/share/vm/runtime/jniHandles.hpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/runtime/jniHandles.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -126,9 +126,17 @@ // Fill block with bad_handle values void zap(); +#ifdef ZERO + protected: + friend class CppInterpreter; +#endif // ZERO + // No more handles in the both the current and following blocks void clear() { _top = 0; } +#ifdef ZERO + private: +#endif // ZERO // Free list computation void rebuild_free_list();
--- a/src/share/vm/runtime/mutex.hpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/runtime/mutex.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -61,18 +61,10 @@ } ; // Endian-ness ... index of least-significant byte in SplitWord.Bytes[] -#ifdef AMD64 // little - #define _LSBINDEX 0 -#else -#if IA32 // little +#ifdef VM_LITTLE_ENDIAN #define _LSBINDEX 0 #else -#ifdef SPARC // big #define _LSBINDEX (sizeof(intptr_t)-1) -#else - #error "unknown architecture" -#endif -#endif #endif class ParkEvent ;
--- a/src/share/vm/runtime/signature.hpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/runtime/signature.hpp Thu Jul 23 15:53:43 2009 +0100 @@ -275,11 +275,14 @@ void do_bool () { pass_int(); _jni_offset++; _offset++; } void do_char () { pass_int(); _jni_offset++; _offset++; } +#if defined(_LP64) || defined(ZERO) + void do_float () { pass_float(); _jni_offset++; _offset++; } +#else + void do_float () { pass_int(); _jni_offset++; _offset++; } +#endif #ifdef _LP64 - void do_float () { pass_float(); _jni_offset++; _offset++; } void do_double() { pass_double(); _jni_offset++; _offset += 2; } #else - void do_float () { pass_int(); _jni_offset++; _offset++; } void do_double() { pass_double(); _jni_offset += 2; _offset += 2; } #endif void do_byte () { pass_int(); _jni_offset++; _offset++; } @@ -303,8 +306,10 @@ virtual void pass_int() = 0; virtual void pass_long() = 0; virtual void pass_object() = 0; +#if defined(_LP64) || defined(ZERO) + virtual void pass_float() = 0; +#endif #ifdef _LP64 - virtual void pass_float() = 0; virtual void pass_double() = 0; #else virtual void pass_double() { pass_long(); } // may be same as long
--- a/src/share/vm/runtime/vm_version.cpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/runtime/vm_version.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -94,8 +94,16 @@ #ifdef TIERED #define VMTYPE "Server" #else - #define VMTYPE COMPILER1_PRESENT("Client") \ - COMPILER2_PRESENT("Server") +#if defined(COMPILER1) || defined(COMPILER2) + #define VMTYPE COMPILER1_PRESENT("Client") \ + COMPILER2_PRESENT("Server") +#else +#ifdef ZERO + #define VMTYPE "Zero" +#else + #define VMTYPE "Core" +#endif // ZERO +#endif // COMPILER1 || COMPILER2 #endif // TIERED #endif // KERNEL @@ -142,10 +150,14 @@ WINDOWS_ONLY("windows") \ SOLARIS_ONLY("solaris") +#ifdef ZERO +#define CPU ZERO_LIBARCH +#else #define CPU IA32_ONLY("x86") \ IA64_ONLY("ia64") \ AMD64_ONLY("amd64") \ SPARC_ONLY("sparc") +#endif // ZERO const char *Abstract_VM_Version::vm_platform_string() { return OS "-" CPU;
--- a/src/share/vm/utilities/vmError.cpp Thu Jul 02 11:10:50 2009 -0700 +++ b/src/share/vm/utilities/vmError.cpp Thu Jul 23 15:53:43 2009 +0100 @@ -25,6 +25,10 @@ # include "incls/_precompiled.incl" # include "incls/_vmError.cpp.incl" +# ifdef ZERO +# include <stackPrinter_zero.hpp> +# endif // ZERO + // List of environment variables that should be reported in error log file. const char *env_list[] = { // All platforms @@ -396,6 +400,7 @@ st->cr(); } +#ifndef ZERO STEP(110, "(printing stack bounds)" ) if (_verbose) { @@ -453,11 +458,16 @@ st->cr(); } } +#endif // !ZERO STEP(130, "(printing Java stack)" ) if (_verbose && _thread && _thread->is_Java_thread()) { JavaThread* jt = (JavaThread*)_thread; +#ifdef ZERO + st->print_cr("Java stack:"); + ZeroStackPrinter(st, buf, sizeof(buf)).print(jt); +#else if (jt->has_last_Java_frame()) { st->print_cr("Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)"); for(StackFrameStream sfs(jt); !sfs.is_done(); sfs.next()) { @@ -465,6 +475,7 @@ st->cr(); } } +#endif // ZERO } STEP(140, "(printing VM operation)" ) @@ -476,6 +487,14 @@ op->print_on_error(st); st->cr(); st->cr(); +#ifdef ZERO + if (op->calling_thread()->is_Java_thread()) { + st->print_cr("Calling thread's Java stack:"); + ZeroStackPrinter(st, buf, sizeof(buf)).print( + (JavaThread *) op->calling_thread()); + st->cr(); + } +#endif // ZERO } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/6855164/Test.java Thu Jul 23 15:53:43 2009 +0100 @@ -0,0 +1,55 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6855164 + * @summary SIGSEGV during compilation of method involving loop over CharSequence + * @run main/othervm -Xbatch Test + */ + +public class Test{ + public static void main(String[] args) throws Exception { + StringBuffer builder = new StringBuffer(); + + for(int i = 0; i < 100; i++) + builder.append("I am the very model of a modern major general\n"); + + for(int j = 0; j < builder.length(); j++){ + previousSpaceIndex(builder, j); + } + } + + private static final int previousSpaceIndex(CharSequence sb, int seek) { + seek--; + while (seek > 0) { + if (sb.charAt(seek) == ' ') { + while (seek > 0 && sb.charAt(seek - 1) == ' ') + seek--; + return seek; + } + seek--; + } + return 0; + } +}