Request to committ to trunk - ARM asm improvements

Edward Nevill ed at camswl.com
Thu Sep 10 11:03:22 PDT 2009


Hi folks,

I have got a bunch of improvements to the ARM asm interpreter which I would
like to commit to the trunk.

Because of the limitations on size of message sent to the list I am sending
the diffs as 3 messages.

The first set (attached below) contains all the diffs to anything other
than cppInterpreter_arm.S and bytecodes_arm.def. IE. it contains all the
non assembler diffs and hence the diffs most likely to interest you.

The second and third set contain the diffs to bytecodes_arm.def and
cppInterpreter_arm.S respectively.

Please check especially that you are happy with the changes to
bytes_zero.hpp and cppInterpreter_zero.cpp

Regards,
Ed.

So, whats new...

----- Makefile.am

I have change the 'mkbc' rule from

	mkbc $< $@

to

	gcc -E - < $< | mkbc - $@

The idea being to allow you to preprocess the .def file before using
mkbc. I have added various #ifdefs to bytecodes_arm.def to allow
various optimisations to be enabled and disabled.

----- mkbc.c

Change to allow the use of '-' as a filename for stdin / stdout. Also
changed to allow '@' as a comment character in addition to '#' to support
the use of gcc preprocessing above.

----- ports/hotspot/build/linux/makefiles/zero.make

Added rules to build 'asm_helper.cpp' and 'mkoffsets'.

Removed the -DHW_NULL_PTR_CHECK. This is the default now. Use
-DDISABLE_HW_NULL_PTR_CHECK if undesired.

----- ports/hotspot/src/cpu/zero/vm/asm_helper.cpp

New source file.

This file serves two purposes.

1) It is built into the JVM image to allow the asm interpreter to access
C++ virtual functions. Previously the asm interpreter had to grub around
inside C++ V tables to call virtuals which was most non portable. Now
it calls a wrapper function in asm_helper.cpp.

2) It is built into the 'mkoffsets' tool to generate the static offsets
within various structures in OpenJDK (most notably the JavaThread
structure). When 'mkoffsets' is run is generates output of the form

#define THREAD_PENDING_EXC		0x04
#define THREAD_SUSPEND_FLAGS		0x18

Thus the offsets are always correct for the version being build. This
reduces the possibility of breakage due to offsets changing between
openjdk versions (as indeed happened between b14 and b16).

Also it allows you to build PRODUCT or DEBUG versions as the offsets
change between PRODUCT and DEBUG versions.

----- ports/hotspot/src/cpu/zero/vm/bytecodes_zero.cpp
----- ports/hotspot/src/cpu/zero/vm/bytecodes_zero.hpp

I have added fast bytecodes of the form

iload_N; iload_N
iload; iload_N
iload_N; iload

This means that the following 4 bytecode sequences can now be
executed as a single bytecode my the ARM interpreter.

<iload - any form><iconst_N><data op><istore - any form>
<iload - any form><iload - any form><data op><istore - any form>

in addition to 3 bytecode varients of the above (ie without the
istore on the end and many other 3 bytecode combinations
(for example <load><load><if_icmp..>).

----- ports/hotspot/src/cpu/zero/vm/bytes_zero.hpp

I have added the 'get_native' and 'get_Java' optimisations discussed
previously on the 'zero' list.

The effect of this change is to use the gcc __attribute__(unaligned)
to load the unaligned data.

A union is defined as follows

typedef union unaligned {
       u4      u;
       u2      us;
       u8      ul;
} __attribute__((packed)) unaligned;

and then, for example, get_native_u2 does

  static inline u2   get_native_u2(address p){
        unaligned *up = (unaligned *)p;
        return up->us;
  }

Note: on x86 this has no effect as x86 permits unaligned accesses.

get_Java_u2 and friends now do byte loads / stores to load / store
the halfword / word / doubleword on little endian machines.

----- ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp

change the

#if defined(PRODUCT) && defined(HOTSPOT_ASM)

to

#ifdef HOTSPOT_ASM

remove the definition of BCI_ENTRY not that generate_entry takes an
address instead of a BCI_ENTRY and changed the definition
of asm_generate_entry to return an address instead of a BCI_ENTRY.
Removed the casts.

Removed the

	if (!UseCompiler && !TaggedStackInterpreter & ...)

Instead it now always calls asm_generate_entry, asm_generate_entry
then tests UseCompiler and TaggedStackInterpreter etc and returns
NULL if it cannot support a particular configuration.

This is better because the knowledge of which configurations are
supported is now embedded in asm_generate_entry instead
of cppInterpreter_zero, which means that cppInterpreter_zero does
not have to continually change to reflect the stack of asm_generate_entry.

----- ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp

removed the #if defined(PRODUCT)

--- CUT HERE ----------------------------------------------------------
diff -ruNE old/icedtea6/Makefile.am new/icedtea6/Makefile.am
--- old/icedtea6/Makefile.am	2009-09-08 14:30:23.000000000 +0100
+++ new/icedtea6/Makefile.am	2009-09-08 15:08:21.000000000 +0100
@@ -469,8 +469,18 @@
 $(abs_top_srcdir)/mkbc: $(abs_top_srcdir)/mkbc.c
 	$(CC) $< -o $@
 
+# ECN: The following rule has been changed to allow preprocessing of the bytecode definition
+# file prior to running 'mkbc'. This allows you to use -DXXX on the gcc command. There are two
+# options currently recognized.
+#
+# -DDISABLE_NOTICE_SAFEPONTS	- Always run in 'safe' mode.
+# -DDISABLE_FAST_BYTECODES	- Disable fast bytecode replacement and bytecode sequences
+#
+# These options are provided mainly to assist debugging by returning the bytecode interpreter
+# to a 'vanilla' interpreter.
+#
 ${ZERO_ASM_BC_ASM}: ${ZERO_ASM_BC_DEF} $(abs_top_srcdir)/mkbc
-	$(abs_top_srcdir)/mkbc $< $@
+	gcc -E - < $< | $(abs_top_srcdir)/mkbc - $@
 
 # Link ports sources into tree
 stamps/ports.stamp: stamps/replace-hotspot.stamp
diff -ruNE old/icedtea6/mkbc.c new/icedtea6/mkbc.c
--- old/icedtea6/mkbc.c	2009-09-08 14:30:24.000000000 +0100
+++ new/icedtea6/mkbc.c	2009-09-08 15:09:22.000000000 +0100
@@ -1,3 +1,17 @@
+/*
+ * Copyright 2009 Edward Nevill
+ *
+ * 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).
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -10,7 +24,7 @@
 #define ISALPHA(c) (isalpha(c) || (c) == '_')
 #define ISALNUM(c) (isalnum(c) || (c) == '_')
 
-FILE *source_f, *bci_f, *bci_f;
+FILE *source_f, *bci_f;
 
 typedef struct Bytecode {
 	char	*name;
@@ -282,7 +296,7 @@
 	c = (readchar)();
 	c = skipwhitespace(c);
 	while (c != EOF) {
-		if (c == '#') {
+		if (c == '@' || c == '#') {
 			c = skipeol(c);
 		} else if (ISALPHA(c)) {
 			c = readsymbol(c, buf, BUFLEN);
@@ -546,7 +560,7 @@
 
 	source = bci = 0;
 	while (s = *++argv) {
-		if (*s == '-') {
+		if (s[0] == '-' && s[1] != 0) {
 			if (s[1] == 'P') {
 				prefix = s+2;
 			} else {
@@ -566,16 +580,26 @@
 		fprintf(stderr, "Too few arguments\n");
 		usage();
 	}
-	source_f = fopen(source, "r");
-	if (!source_f) fatal("Error opening source file");
-	bci_f = fopen(bci, "w");
-	if (!bci_f) fatal("Error opening bci file for write");
+	if (strcmp(source, "-") == 0) {
+		source_f = stdin;
+	} else {
+		source_f = fopen(source, "r");
+		if (!source_f) fatal("Error opening source file");
+	}
+	if (strcmp(bci, "-") == 0) {
+		bci_f = stdout;
+	} else {
+		bci_f = fopen(bci, "w");
+		if (!bci_f) fatal("Error opening bci file for write");
+	}
 	for (i = 0; i < 256; i++) {
 		bytecodes[i].name = "undefined";
 		bytecodes[i].len = -1;
 	}
 	mkbc();
 	dumpbc();
-	if (fclose(source_f)) fatal("Error reading source");
-	if (fclose(bci_f)) fatal("Error writing bci");
+	if (ferror(source_f)) fatal("Error reading source");
+	if (ferror(bci_f)) fatal("Error writing bci");
+	if (source_f != stdin) fclose(source_f);
+	if (bci_f != stdout) fclose(bci_f);
 }
diff -ruNE old/icedtea6/ports/hotspot/build/linux/makefiles/zero.make new/icedtea6/ports/hotspot/build/linux/makefiles/zero.make
--- old/icedtea6/ports/hotspot/build/linux/makefiles/zero.make	2009-09-08 14:30:25.000000000 +0100
+++ new/icedtea6/ports/hotspot/build/linux/makefiles/zero.make	2009-09-10 14:17:01.000000000 +0100
@@ -24,12 +24,28 @@
 #
 
 ifeq ($(ZERO_LIBARCH),arm)
+
+Obj_Files += asm_helper.o
 Obj_Files += cppInterpreter_arm.o
-CFLAGS += -DHOTSPOT_ASM -DHW_NULL_PTR_CHECK
+
+CFLAGS += -DHOTSPOT_ASM
+
 %.o: %.S
 	@echo Assembling $<
 	$(QUIETLY) $(REMOVE_TARGET)
 	$(COMPILE.CC) -o $@ $< $(COMPILE_DONE)
+
+cppInterpreter_arm.o:	offsets_arm.s
+
+offsets_arm.s:	mkoffsets
+	@echo Generating assembler offsets
+	./mkoffsets > $@
+
+mkoffsets:	asm_helper.cpp
+	@echo Compiling offset generator
+	$(QUIETLY) $(REMOVE_TARGET)
+	$(CC_COMPILE) -DSTATIC_OFFSETS -o $@ $< $(COMPILE_DONE)
+
 endif
 
 # The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized
diff -ruNE old/icedtea6/ports/hotspot/src/cpu/zero/vm/asm_helper.cpp new/icedtea6/ports/hotspot/src/cpu/zero/vm/asm_helper.cpp
--- old/icedtea6/ports/hotspot/src/cpu/zero/vm/asm_helper.cpp	1970-01-01 01:00:00.000000000 +0100
+++ new/icedtea6/ports/hotspot/src/cpu/zero/vm/asm_helper.cpp	2009-09-08 14:33:40.000000000 +0100
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2009 Edward Nevill
+ *
+ * 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).
+ */
+
+#include "incls/_precompiled.incl"
+
+#ifndef STATIC_OFFSETS
+
+extern "C" void sanity_check_backtrace(ZeroFrame *frame, int *regs);
+
+extern "C" void check_java_threads_backtrace(int *regs)
+{
+  for (JavaThread* jt = Threads::first(); jt != NULL; jt = jt->next()) {
+    if (jt->threadObj() == NULL   ||
+        jt->is_exiting() ||
+        !java_lang_Thread::is_alive(jt->threadObj())   ||
+        jt->is_hidden_from_external_view()) {
+      continue;
+    }
+    if (jt->is_jvmti_agent_thread()) continue;
+    if (jt->is_attaching()) continue;
+    sanity_check_backtrace(jt->top_zero_frame(), regs);
+  }
+}
+
+/* Thease functions allow the ASM interpreter to call CPP virtual functions.
+ * Otherwise the ASM interpreter has to grup around in the VTABLE which is
+ * not very portable.
+ */
+extern "C" bool JavaThread_is_lock_owned(JavaThread *r0, address r1)
+{
+	return r0->is_lock_owned(r1);
+}
+
+extern "C" HeapWord **CollectedHeap_top_addr(CollectedHeap *r0)
+{
+	return r0->top_addr();
+}
+
+extern "C" HeapWord **CollectedHeap_end_addr(CollectedHeap *r0)
+{
+	return r0->end_addr();
+}
+
+#endif // STATIC_OFFSETS
+
+#ifdef STATIC_OFFSETS
+
+class VMStructs {
+public:
+	static void print_vm_offsets(void);
+};
+
+#define outfile	stdout
+
+void print_def(const char *s, int v)
+{
+	fprintf(outfile, "#define %-40s 0x%02x\n", s, v);
+}
+
+void nl(void)
+{
+	fputc('\n', outfile);
+}
+
+void VMStructs::print_vm_offsets(void)
+{
+	print_def("THREAD_PENDING_EXC", offset_of(JavaThread, _pending_exception));
+	print_def("THREAD_SUSPEND_FLAGS", offset_of(JavaThread, _suspend_flags));
+	print_def("THREAD_ACTIVE_HANDLES", offset_of(JavaThread, _active_handles));
+	print_def("THREAD_LAST_HANDLE_MARK", offset_of(JavaThread, _last_handle_mark));
+	print_def("THREAD_TLAB_TOP", offset_of(JavaThread, _tlab) + offset_of(ThreadLocalAllocBuffer, _top));
+	print_def("THREAD_TLAB_END", offset_of(JavaThread, _tlab) + offset_of(ThreadLocalAllocBuffer, _end));
+	print_def("THREAD_RESOURCEAREA", offset_of(JavaThread, _resource_area));
+	print_def("THREAD_HANDLE_AREA", offset_of(JavaThread, _handle_area));
+	print_def("THREAD_STACK_BASE", offset_of(JavaThread, _stack_base));
+	print_def("THREAD_STACK_SIZE", offset_of(JavaThread, _stack_size));
+	print_def("THREAD_LAST_JAVA_SP", offset_of(JavaThread, _anchor) + offset_of(JavaFrameAnchor, _last_Java_sp));
+	print_def("THREAD_JNI_ENVIRONMENT", offset_of(JavaThread, _jni_environment));
+	print_def("THREAD_VM_RESULT", offset_of(JavaThread, _vm_result));
+	print_def("THREAD_STATE", offset_of(JavaThread, _thread_state));
+	print_def("THREAD_DO_NOT_UNLOCK", offset_of(JavaThread, _do_not_unlock_if_synchronized));
+
+	print_def("THREAD_JAVA_STACK_BASE", offset_of(JavaThread, _zero_stack) + ZeroStack::base_offset());
+	print_def("THREAD_JAVA_SP", offset_of(JavaThread, _zero_stack) + ZeroStack::sp_offset());
+	print_def("THREAD_TOP_ZERO_FRAME", offset_of(JavaThread, _top_zero_frame));
+	print_def("THREAD_SPECIALRUNTIMEEXITCONDITION", offset_of(JavaThread, _special_runtime_exit_condition));
+	nl();
+	print_def("_thread_external_suspend",	Thread::_external_suspend);
+	print_def("_thread_ext_suspended",	Thread::_ext_suspended);
+	print_def("_thread_deopt_suspend",	Thread::_deopt_suspend);
+	nl();
+	print_def("METHOD_CONSTMETHOD", offset_of(methodOopDesc, _constMethod));
+	print_def("METHOD_CONSTANTS", offset_of(methodOopDesc, _constants));
+	print_def("METHOD_METHODDATA", offset_of(methodOopDesc, _method_data));
+	print_def("METHOD_INVOKECOUNT", offset_of(methodOopDesc, _interpreter_invocation_count));
+	print_def("METHOD_ACCESSFLAGS", offset_of(methodOopDesc, _access_flags));
+	print_def("METHOD_VTABLEINDEX", offset_of(methodOopDesc, _vtable_index));
+	print_def("METHOD_RESULTINDEX", offset_of(methodOopDesc, _result_index));
+	print_def("METHOD_METHODSIZE", offset_of(methodOopDesc, _method_size));
+	print_def("METHOD_MAXSTACK", offset_of(methodOopDesc, _max_stack));
+	print_def("METHOD_MAXLOCALS", offset_of(methodOopDesc, _max_locals));
+	print_def("METHOD_SIZEOFPARAMETERS", offset_of(methodOopDesc, _size_of_parameters));
+	print_def("METHOD_INVOCATIONCOUNTER", offset_of(methodOopDesc, _invocation_counter));
+	print_def("METHOD_BACKEDGECOUNTER", offset_of(methodOopDesc, _backedge_counter));
+	print_def("METHOD_FROM_INTERPRETED", offset_of(methodOopDesc, _from_interpreted_entry));
+	// ECN: These two appear to be just tagged onto the end of the class
+	print_def("METHOD_NATIVEHANDLER", sizeof(methodOopDesc));
+	print_def("METHOD_SIGNATUREHANDLER", sizeof(methodOopDesc)+4);
+	nl();
+	print_def("CONSTMETHOD_CODEOFFSET", sizeof(constMethodOopDesc));
+	nl();
+	print_def("JNIHANDLEBLOCK_TOP", offset_of(JNIHandleBlock, _top));
+	nl();
+	print_def("KLASS_PART", klassOopDesc::klass_part_offset_in_bytes());
+	print_def("KLASS_ACCESSFLAGS", offset_of(Klass, _access_flags));
+	print_def("INSTANCEKLASS_INITSTATE", offset_of(instanceKlass, _init_state));
+	print_def("INSTANCEKLASS_VTABLE_LEN", offset_of(instanceKlass, _vtable_len));
+	print_def("INSTANCEKLASS_ITABLE_LEN", offset_of(instanceKlass, _itable_len));
+	print_def("INSTANCEKLASS_VTABLE_OFFSET", instanceKlass::vtable_start_offset() * sizeof(int *));
+	print_def("OBJARRAYKLASS_ELEMENTKLASS", offset_of(objArrayKlass, _element_klass));
+	nl();
+	print_def("CONSTANTPOOL_TAGS", offset_of(constantPoolOopDesc, _tags));
+	print_def("CONSTANTPOOL_CACHE", offset_of(constantPoolOopDesc, _cache));
+	nl();
+	print_def("SIZEOF_HANDLEMARK", sizeof(HandleMark));
+}
+
+int main(void)
+{
+	print_def("JVM_CONSTANT_Utf8",		JVM_CONSTANT_Utf8);
+	print_def("JVM_CONSTANT_Unicode",	JVM_CONSTANT_Unicode);
+	print_def("JVM_CONSTANT_Integer",	JVM_CONSTANT_Integer);
+	print_def("JVM_CONSTANT_Float",		JVM_CONSTANT_Float);
+	print_def("JVM_CONSTANT_Long",		JVM_CONSTANT_Long);
+	print_def("JVM_CONSTANT_Double",	JVM_CONSTANT_Double);
+	print_def("JVM_CONSTANT_Class",		JVM_CONSTANT_Class);
+	print_def("JVM_CONSTANT_String",	JVM_CONSTANT_String);
+	print_def("JVM_CONSTANT_Fieldref",	JVM_CONSTANT_Fieldref);
+	print_def("JVM_CONSTANT_Methodref",	JVM_CONSTANT_Methodref);
+	print_def("JVM_CONSTANT_InterfaceMethodref", JVM_CONSTANT_InterfaceMethodref);
+	print_def("JVM_CONSTANT_NameAndType",	JVM_CONSTANT_NameAndType);
+	nl();
+	print_def("JVM_CONSTANT_UnresolvedClass",	JVM_CONSTANT_UnresolvedClass);
+	print_def("JVM_CONSTANT_ClassIndex",		JVM_CONSTANT_ClassIndex);
+	print_def("JVM_CONSTANT_UnresolvedString",	JVM_CONSTANT_UnresolvedString);
+	print_def("JVM_CONSTANT_StringIndex",		JVM_CONSTANT_StringIndex);
+	print_def("JVM_CONSTANT_UnresolvedClassInError",JVM_CONSTANT_UnresolvedClassInError);
+	nl();
+	print_def("JVM_ACC_PUBLIC",	JVM_ACC_PUBLIC);
+	print_def("JVM_ACC_PRIVATE",	JVM_ACC_PRIVATE);
+	print_def("JVM_ACC_PROTECTED",	JVM_ACC_PROTECTED);
+	print_def("JVM_ACC_STATIC",	JVM_ACC_STATIC);
+	print_def("JVM_ACC_FINAL",	JVM_ACC_FINAL);
+	print_def("JVM_ACC_SYNCHRONIZED",	JVM_ACC_SYNCHRONIZED);
+	print_def("JVM_ACC_SUPER",	JVM_ACC_SUPER);
+	print_def("JVM_ACC_VOLATILE",	JVM_ACC_VOLATILE);
+	print_def("JVM_ACC_BRIDGE",	JVM_ACC_BRIDGE);
+	print_def("JVM_ACC_TRANSIENT",	JVM_ACC_TRANSIENT);
+	print_def("JVM_ACC_VARARGS",	JVM_ACC_VARARGS);
+	print_def("JVM_ACC_NATIVE",	JVM_ACC_NATIVE);
+	print_def("JVM_ACC_INTERFACE",	JVM_ACC_INTERFACE);
+	print_def("JVM_ACC_ABSTRACT",	JVM_ACC_ABSTRACT);
+	print_def("JVM_ACC_STRICT",	JVM_ACC_STRICT);
+	print_def("JVM_ACC_SYNTHETIC",	JVM_ACC_SYNTHETIC);
+	print_def("JVM_ACC_ANNOTATION",	JVM_ACC_ANNOTATION);
+	print_def("JVM_ACC_ENUM",	JVM_ACC_ENUM);
+	print_def("JVM_ACC_HAS_FINALIZER", JVM_ACC_HAS_FINALIZER);
+	nl();
+	print_def("T_BOOLEAN",	T_BOOLEAN);
+	print_def("T_CHAR",	T_CHAR);
+	print_def("T_FLOAT",	T_FLOAT);
+	print_def("T_DOUBLE",	T_DOUBLE);
+	print_def("T_BYTE",	T_BYTE);
+	print_def("T_SHORT",	T_SHORT);
+	print_def("T_INT",	T_INT);
+	print_def("T_LONG",	T_LONG);
+	print_def("T_OBJECT",	T_OBJECT);
+	print_def("T_ARRAY",	T_ARRAY);
+	print_def("T_VOID",	T_VOID);
+	nl();
+	print_def("_thread_uninitialized",	_thread_uninitialized);
+	print_def("_thread_new",		_thread_new);
+	print_def("_thread_new_trans",		_thread_new_trans);
+	print_def("_thread_in_native",		_thread_in_native);
+	print_def("_thread_in_native_trans",	_thread_in_native_trans);
+	print_def("_thread_in_vm",		_thread_in_vm);
+	print_def("_thread_in_vm_trans",	_thread_in_vm_trans);
+	print_def("_thread_in_Java",		_thread_in_Java);
+	print_def("_thread_in_Java_trans",	_thread_in_Java_trans);
+	print_def("_thread_blocked",		_thread_blocked);
+	print_def("_thread_blocked_trans",	_thread_blocked_trans);
+	print_def("_thread_max_state",		_thread_max_state);
+	nl();
+	print_def("class_unparsable_by_gc",	instanceKlass::unparsable_by_gc);
+	print_def("class_allocated",		instanceKlass::allocated);
+	print_def("class_loaded",		instanceKlass::loaded);
+	print_def("class_linked",		instanceKlass::linked);
+	print_def("class_being_initialized",	instanceKlass::being_initialized);
+	print_def("class_fully_initialized",	instanceKlass::fully_initialized);
+	print_def("class_init_error",		instanceKlass::initialization_error);
+	nl();
+	print_def("flag_methodInterface",	1 << ConstantPoolCacheEntry::methodInterface);
+	print_def("flag_volatileField",		1 << ConstantPoolCacheEntry::volatileField);
+	print_def("flag_vfinalMethod",		1 << ConstantPoolCacheEntry::vfinalMethod);
+	print_def("flag_finalField",		1 << ConstantPoolCacheEntry::finalField);
+	nl();
+	print_def("INVOCATIONCOUNTER_COUNTINCREMENT", InvocationCounter::count_increment);
+	nl();
+	VMStructs::print_vm_offsets();
+	nl();
+	print_def("VMSYMBOLS_ArithmeticException", vmSymbols::java_lang_ArithmeticException_enum);
+	print_def("VMSYMBOLS_ArrayIndexOutOfBounds", vmSymbols::java_lang_ArrayIndexOutOfBoundsException_enum);
+	print_def("VMSYMBOLS_ArrayStoreException", vmSymbols::java_lang_ArrayStoreException_enum);
+	print_def("VMSYMBOLS_ClassCastException", vmSymbols::java_lang_ClassCastException_enum);
+	print_def("VMSYMBOLS_NullPointerException", vmSymbols::java_lang_NullPointerException_enum);
+	print_def("VMSYMBOLS_AbstractMethodError", vmSymbols::java_lang_AbstractMethodError_enum);
+	print_def("VMSYMBOLS_IncompatibleClassChangeError", vmSymbols::java_lang_IncompatibleClassChangeError_enum);
+	print_def("VMSYMBOLS_InternalError", vmSymbols::java_lang_InternalError_enum);
+
+	return 0;
+}
+
+#endif // STATIC_OFFSETS
diff -ruNE old/icedtea6/ports/hotspot/src/cpu/zero/vm/bytecodes_zero.cpp new/icedtea6/ports/hotspot/src/cpu/zero/vm/bytecodes_zero.cpp
--- old/icedtea6/ports/hotspot/src/cpu/zero/vm/bytecodes_zero.cpp	2009-09-08 14:30:25.000000000 +0100
+++ new/icedtea6/ports/hotspot/src/cpu/zero/vm/bytecodes_zero.cpp	2009-09-08 14:55:59.000000000 +0100
@@ -26,19 +26,27 @@
 #include "incls/_precompiled.incl"
 #include "incls/_bytecodes_zero.cpp.incl"
 
-void Bytecodes::pd_initialize() {
-#if defined(PRODUCT) && defined(HOTSPOT_ASM)
+void Bytecodes::pd_initialize()
+{
+  // No zero specific initialization
+#ifdef HOTSPOT_ASM
   def(_iaccess_0, "_iaccess_0", "b_jj", NULL, T_INT,  1, true, _aload_0);
   def(_iaccess_1, "_iaccess_1", "b_jj", NULL, T_INT,  1, true, _aload_1);
   def(_iaccess_2, "_iaccess_2", "b_jj", NULL, T_INT,  1, true, _aload_2);
   def(_iaccess_3, "_iaccess_3", "b_jj", NULL, T_INT,  1, true, _aload_3);
 
+  def(_invokeresolved,   "invokeresolved",   "bjj", NULL, T_ILLEGAL, -1, true, _invokevirtual);
+  def(_invokespecialresolved, "invokespecialresolved", "bjj", NULL, T_ILLEGAL, -1, true, _invokespecial);
+  def(_invokestaticresolved,  "invokestaticresolved",  "bjj", NULL, T_ILLEGAL,  0, true, _invokestatic);
+
+  def(_iload_iload,	 "iload_iload",      "bi_i",NULL, T_INT, 2, false, _iload);
+  def(_iload_iload_N,	 "ilaod_iload_N",    "bi_", NULL, T_INT, 2, false, _iload);
+
   def(_iload_0_iconst_N, "iload_0_iconst_N", "b_",  NULL, T_INT, 2, false, _iload_0);
   def(_iload_1_iconst_N, "iload_1_iconst_N", "b_",  NULL, T_INT, 2, false, _iload_1);
   def(_iload_2_iconst_N, "iload_2_iconst_N", "b_",  NULL, T_INT, 2, false, _iload_2);
   def(_iload_3_iconst_N, "iload_3_iconst_N", "b_",  NULL, T_INT, 2, false, _iload_3);
   def(_iload_iconst_N,   "iload_iconst_N",   "bi_", NULL, T_INT, 2, false, _iload);
-  def(_invokeresolved,   "invokeresolved",   "bjj", NULL, T_ILLEGAL, -1, true, _invokevirtual);
 
   def(_iadd_istore_N,    "iadd_istore_N",    "b_",  NULL, T_VOID, -2, false, _iadd);
   def(_isub_istore_N,    "isub_istore_N",    "b_",  NULL, T_VOID, -2, false, _isub);
@@ -52,7 +60,15 @@
   def(_ior_u4store,      "ior_u4store",      "b_i", NULL, T_VOID, -2, false, _ior);
   def(_ixor_u4store,     "ixor_u4store",     "b_i", NULL, T_VOID, -2, false, _ixor);
 
-  def(_invokespecialresolved, "invokespecialresolved", "bjj", NULL, T_ILLEGAL, -1, true, _invokespecial);
-  def(_invokestaticresolved,  "invokestaticresolved",  "bjj", NULL, T_ILLEGAL,  0, true, _invokestatic);
-#endif // HOTSPOT_ASM
+  def(_iload_0_iload,	 "iload_0_iload",    "b_i", NULL, T_INT, 2, false, _iload_0);
+  def(_iload_1_iload,	 "iload_1_iload",    "b_i", NULL, T_INT, 2, false, _iload_1);
+  def(_iload_2_iload,	 "iload_2_iload",    "b_i", NULL, T_INT, 2, false, _iload_2);
+  def(_iload_3_iload,	 "iload_3_iload",    "b_i", NULL, T_INT, 2, false, _iload_3);
+
+  def(_iload_0_iload_N,	 "iload_0_iload_N",  "b_",  NULL, T_INT, 2, false, _iload_0);
+  def(_iload_1_iload_N,	 "iload_1_iload_N",  "b_",  NULL, T_INT, 2, false, _iload_1);
+  def(_iload_2_iload_N,	 "iload_2_iload_N",  "b_",  NULL, T_INT, 2, false, _iload_2);
+  def(_iload_3_iload_N,	 "iload_3_iload_N",  "b_",  NULL, T_INT, 2, false, _iload_3);
+
+#endif
 }
diff -ruNE old/icedtea6/ports/hotspot/src/cpu/zero/vm/bytecodes_zero.hpp new/icedtea6/ports/hotspot/src/cpu/zero/vm/bytecodes_zero.hpp
--- old/icedtea6/ports/hotspot/src/cpu/zero/vm/bytecodes_zero.hpp	2009-09-08 14:30:25.000000000 +0100
+++ new/icedtea6/ports/hotspot/src/cpu/zero/vm/bytecodes_zero.hpp	2009-09-08 14:56:18.000000000 +0100
@@ -1,49 +1,37 @@
-/*
- * 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.
- *
- */
-
-#if defined(PRODUCT) && defined(HOTSPOT_ASM)
+#ifdef HOTSPOT_ASM
 #define _iaccess_0	((Bytecodes::Code)0xdb)
 #define _iaccess_1	((Bytecodes::Code)0xdc)
 #define _iaccess_2	((Bytecodes::Code)0xdd)
 #define _iaccess_3	((Bytecodes::Code)0xde)
+
+#define _invokeresolved		((Bytecodes::Code)0xdf)
+#define	_invokespecialresolved	((Bytecodes::Code)0xe0)
+#define _invokestaticresolved	((Bytecodes::Code)0xe1)
+
+#define _iload_iload	((Bytecodes::Code)0xe3)
+#define _iload_iload_N	((Bytecodes::Code)0xe4)
+
 	_iload_0_iconst_N	,	// 231
 	_iload_1_iconst_N	,	// 232
 	_iload_2_iconst_N	,	// 233
 	_iload_3_iconst_N	,	// 234
 	_iload_iconst_N		,	// 235
-	_invokeresolved		,	// 236
-	_iadd_istore_N		,	// 237
-	_isub_istore_N		,	// 238
-	_iand_istore_N		,	// 239
-	_ior_istore_N		,	// 240
-	_ixor_istore_N		,	// 241
-	_iadd_u4store		,	// 242
-	_isub_u4store		,	// 243
-	_iand_u4store		,	// 244
-	_ior_u4store		,	// 245
-	_ixor_u4store		,	// 246
-	_invokespecialresolved	,	// 247
-	_invokestaticresolved	,	// 248
-#endif // HOTSPOT_ASM
+	_iadd_istore_N		,	// 236
+	_isub_istore_N		,	// 237
+	_iand_istore_N		,	// 238
+	_ior_istore_N		,	// 239
+	_ixor_istore_N		,	// 240
+	_iadd_u4store		,	// 241
+	_isub_u4store		,	// 242
+	_iand_u4store		,	// 243
+	_ior_u4store		,	// 244
+	_ixor_u4store		,	// 245
+	_iload_0_iload		,	// 246
+	_iload_1_iload		,	// 247
+	_iload_2_iload		,	// 248
+	_iload_3_iload		,	// 249
+	_iload_0_iload_N	,	// 250
+	_iload_1_iload_N	,	// 251
+	_iload_2_iload_N	,	// 252
+	_iload_3_iload_N	,	// 253
+#endif
diff -ruNE old/icedtea6/ports/hotspot/src/cpu/zero/vm/bytes_zero.hpp new/icedtea6/ports/hotspot/src/cpu/zero/vm/bytes_zero.hpp
--- old/icedtea6/ports/hotspot/src/cpu/zero/vm/bytes_zero.hpp	2009-09-08 14:30:25.000000000 +0100
+++ new/icedtea6/ports/hotspot/src/cpu/zero/vm/bytes_zero.hpp	2009-09-10 14:32:44.000000000 +0100
@@ -23,6 +23,12 @@
  *
  */
 
+typedef union unaligned {
+	u4	u;
+	u2	us;
+	u8	ul;
+} __attribute__((packed)) unaligned;
+
 class Bytes: AllStatic {
  public:
   // Returns true if the byte ordering used by Java is different
@@ -37,197 +43,35 @@
 
   // 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])      );
+	unaligned *up = (unaligned *)p;
+	return up->us;
   }
 
   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]);
-    }
+	unaligned *up = (unaligned *)p;
+	return up->u;
   }
 
   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]);
-    }
+	unaligned *up = (unaligned *)p;
+	return up->ul;
   }
 
   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;
-    }
+	unaligned *up = (unaligned *)p;
+	up->us = 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;
-    }
+	unaligned *up = (unaligned *)p;
+	up->u = x;
   }
 
   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;
-    }
+	unaligned *up = (unaligned *)p;
+	up->ul = 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
@@ -235,23 +79,40 @@
 #ifdef VM_LITTLE_ENDIAN
   // Byte-order reversal is needed
   static inline u2 get_Java_u2(address p) {
-    return swap_u2(get_native_u2(p));
+    return ( u2(p[0]) << 8 ) | ( u2(p[1])      );
   }
   static inline u4 get_Java_u4(address p) {
-    return swap_u4(get_native_u4(p));
+    return ( u4(p[0]) << 24 ) | ( u4(p[1]) << 16 ) | ( u4(p[2]) << 8 ) | ( u4(p[3]) );
   }
   static inline u8 get_Java_u8(address p) {
-    return swap_u8(get_native_u8(p));
+    u4 hi, lo;
+    hi = ( u4(p[0]) << 24 ) | ( u4(p[1]) << 16 ) | ( u4(p[2]) << 8 ) | ( u4(p[3]) );
+    lo = ( u4(p[4]) << 24 ) | ( u4(p[5]) << 16 ) | ( u4(p[6]) << 8 ) | ( u4(p[7]) );
+    return u8(lo) | (u8(hi) << 32);
   }
 
   static inline void put_Java_u2(address p, u2 x) {
-    put_native_u2(p, swap_u2(x));
+    p[0] = x >> 8;
+    p[1] = x;
   }
   static inline void put_Java_u4(address p, u4 x) {
-    put_native_u4(p, swap_u4(x));
+    p[0] = x >> 24;
+    p[1] = x >> 16;
+    p[2] = x >> 8;
+    p[3] = x;
   }
   static inline void put_Java_u8(address p, u8 x) {
-    put_native_u8(p, swap_u8(x));
+    u4 hi, lo;
+    lo = x;
+    hi = x >> 32;
+    p[0] = hi >> 24;
+    p[1] = hi >> 16;
+    p[2] = hi >> 8;
+    p[3] = hi;
+    p[4] = lo >> 24;
+    p[5] = lo >> 16;
+    p[6] = lo >> 8;
+    p[7] = lo;
   }
 
   // Efficient swapping of byte ordering
diff -ruNE old/icedtea6/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp new/icedtea6/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
--- old/icedtea6/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	2009-09-08 14:30:25.000000000 +0100
+++ new/icedtea6/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	2009-09-08 14:50:09.000000000 +0100
@@ -719,9 +719,8 @@
   return generate_entry((address) CppInterpreter::normal_entry);
 }
 
-#if defined(PRODUCT) && defined(HOTSPOT_ASM)
-typedef void (*BCI_ENTRY)(methodOopDesc*, intptr_t, Thread*);
-extern "C" BCI_ENTRY asm_generate_method_entry(
+#ifdef HOTSPOT_ASM
+extern "C" address asm_generate_method_entry(
   AbstractInterpreter::MethodKind kind);
 #endif // HOTSPOT_ASM
 
@@ -729,14 +728,10 @@
     AbstractInterpreter::MethodKind kind) {
   address entry_point = NULL;
 
-#if defined(PRODUCT) && defined(HOTSPOT_ASM)
-  if (!UseCompiler && !TaggedStackInterpreter &&
-      !JvmtiExport::can_post_interpreter_events() &&
-      !PrintCommandLineFlags) {
-    address asm_entry = (address) asm_generate_method_entry(kind);
+#ifdef HOTSPOT_ASM
+    address asm_entry = asm_generate_method_entry(kind);
     if (asm_entry)
       return ((InterpreterGenerator*) this)->generate_entry(asm_entry);
-  }
 #endif // HOTSPOT_ASM
 
   switch (kind) {
diff -ruNE old/icedtea6/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp new/icedtea6/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp
--- old/icedtea6/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	2009-09-08 14:30:25.000000000 +0100
+++ new/icedtea6/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	2009-09-08 14:54:17.000000000 +0100
@@ -71,7 +71,7 @@
   Unimplemented();
 }
 
-#if defined(PRODUCT) && defined(HOTSPOT_ASM)
+#ifdef HOTSPOT_ASM
 extern "C" int asm_check_null_ptr(ucontext_t *uc);
 #endif // HOTSPOT_ASM
 
@@ -82,7 +82,7 @@
                         int abort_if_unrecognized) {
   ucontext_t* uc = (ucontext_t*) ucVoid;
 
-#if defined(PRODUCT) && defined(HOTSPOT_ASM)
+#ifdef HOTSPOT_ASM
   if (sig == SIGSEGV) {
         if (asm_check_null_ptr(uc)) return 1;
   }



More information about the distro-pkg-dev mailing list