public inbox for java@gcc.gnu.org
 help / color / mirror / Atom feed
* Create binary from GCJ generated assembly
@ 2009-10-27  8:22 isuru herath
  2009-10-27  9:42 ` Andrew Haley
  0 siblings, 1 reply; 8+ messages in thread
From: isuru herath @ 2009-10-27  8:22 UTC (permalink / raw)
  To: java

Dear All,

I want to add two assembly instructions to my Java program. Earlier I was doing it in C with "asm volatile". To get the same behavior in Java I used JNI. I used GCJ with -fjni flat to crate the binary. It executed and gave the correct output. But when I checked the memory references between two assembly instructions it is very high compared to the C program.  Thereafter I got the assembly version of both C and Java codes with -S option. In C version, assembly instructions are directly inserted in the proper places. But in Java version library calls are placed in the places where assembly should be inserted. I doubt this may be the case for larger memory references. So my question is is there a way to edit the gcj generated assembly and insert assembly instructions and compile it to a binary. I tried two different ways(trial and error). Nothing worked.

[1]
gcj --main=new_shared_counter -o new_shared_counter new_shared_counter.s

[2]
gcc shared_counter.s

Any help on how to compile a gcj generated assembly to binary would be greatly appreciated.

regards,
Isuru      


      

^ permalink raw reply	[flat|nested] 8+ messages in thread
* Re: Create binary from GCJ generated assembly
@ 2009-10-28 18:12 isuru herath
  2009-10-28 18:32 ` Andrew Haley
  0 siblings, 1 reply; 8+ messages in thread
From: isuru herath @ 2009-10-28 18:12 UTC (permalink / raw)
  To: Andrew Haley; +Cc: java

[-- Attachment #1: Type: text/plain, Size: 3152 bytes --]

Hi Andrew,

Thanks for the reply. My code is attached.

My intention of using this xchg instruction is that the simulator[Simics] I am using recognizes them as an special event and I can start counting the memory reference from that point onwards. I am trying this on Java is because we are going to use benchmark programs written Java. Thats why I am trying to use CNI to insert assembly to the binary.

I dont understand what you mean by "intrinsic counter". I would greatly appreciate if you could explain it bit more if you have time.

Aslo I didn get clearly what you mean by
 
Personally speaking, I'd just write the routines that need to access the counter in C++.

I am trying to find a way to insert these two assembly instructions to the binary created by gcj so that it will give the same number of memory references as C programs does.

thanks a lot for your help. further help is greatly appreciated.

regards,
isuru

--- On Wed, 10/28/09, Andrew Haley <aph@redhat.com> wrote:

> From: Andrew Haley <aph@redhat.com>
> Subject: Re: Create binary from GCJ generated assembly
> To: "isuru herath" <isuru81@yahoo.com>
> Cc: java@gcc.gnu.org
> Date: Wednesday, October 28, 2009, 8:56 AM
> isuru herath wrote:
> 
> > Thanks a lot for the quick reply. I did accordingly.
> But results were not the same. My program is a multi
> threaded shared counter.
> > so in my Java code I have 
> > counter++
> > 
> > I need to surround this with two xchg instructions.
> like
> > 
> > xchg
> > counter++
> > xchg
> > 
> > so that I can count number of read and write
> operations between two xchg instructions.
> 
> OK.
> 
> > with gcc I got both as 1 which is correct.
> > with gcj and JNI I got 47 read operations and 29 write
> operations
> > with gcj and CNI I got 6 read operations and 6 write
> operations
> > 
> > the way I am doing with CNI is follows.
> > 1. a java class with native method.(custom.java)
> > 2. c++ implementation of it to insert
> assembly.(custom.cc)
> > 3. compile custom.java (gcj -C custom.java)
> > 4. create the header file (gcjh custom -o custom.h)
> > 5. write multi threaded shared counter program. it has
> calls to native method to insert
> assembly(shared_counter.java)
> > 6. compile all java classes (gcj -C *.java)
> > 7. compile the custom.cc (g++ -c custom.cc -o
> custom.o)
> > 8. create the executable. (gcj do_options.class
> custom.class shared_counter.class custom.o -lstdc++
> --main=shared_counter -o shared_conter)
> > 
> > do_options is an interface with final variables. is
> there something that is wrong. or should I need do some
> additional thing. any help/ advice is greatly appreciated.
> 
> I'd rather see your code than guess what you did.
> 
> But yes, you're right.  You'd be calling code to
> invoke the inline asm,
> rather than executing it directly.  If you can't
> tolerate that, your
> only recourse is to add an intrinsic counter
> increment.  gcj already has
> intrinsics for things like
> sun.misc.Unsafe.compareAndSwapInt(), so this one
> should be easy enough.  Personally speaking, I'd just
> write the routines
> that need to access the counter in C++.
> 
> Andrew.
> 
>


      

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: custom.cc --]
[-- Type: text/x-c++src; name="custom.cc", Size: 670 bytes --]

#define _GNU_SOURCE
#include <gcj/cni.h>
#include <pthread.h>
#include <iostream>
#include "custom.h"
#include "java_magic_c.h"


using namespace std;
using namespace java::lang;

void
custom::do_this(jint option)
{
	MAGIC(option);
}

jint
custom::bind_this_thread(jlong thread_id)
{
// 	Mask for achieve the hard coded processor affinity
	cpu_set_t mask;
// 	Initializes all the bits in the mask to zero
	CPU_ZERO(&mask);
// 	Sets only the bits corresponding to the cpu
	CPU_SET(thread_id, &mask);

	if(sched_setaffinity(0, sizeof(mask), &mask) == -1 )
	{
		cout << "Thread"<< (int)thread_id << ": WARNING: Could not set CPU Affinity, continuing...\n";
	}
	return 0;
}

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: custom.h --]
[-- Type: text/x-chdr; name="custom.h", Size: 434 bytes --]

// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-

#ifndef __custom__
#define __custom__

#pragma interface

#include <java/lang/Object.h>

extern "Java"
{
  class custom;
}

class custom : public ::java::lang::Object
{
public:
  static void do_this (jint);
  static jint bind_this_thread (jlong);
public: // actually package-private
  custom ();
public:

  static ::java::lang::Class class$;
};

#endif /* __custom__ */

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: custom.java --]
[-- Type: text/x-java; name="custom.java", Size: 124 bytes --]

class custom
{
	public static native void do_this(int option);
	public static native int bind_this_thread(long thread_id);
}

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: do_options.java --]
[-- Type: text/x-java; name="do_options.java", Size: 313 bytes --]

interface do_options
{
	int TX_ABORT		= 0xA;
	int TX_BEGIN		= 0xB;
	int TX_COMMIT		= 0xC;
	int TX_PRINT		= 0xD;

	int RW_PRIVATE		= 0x1;
	int RO_SHARED		= 0x2;
	int R_SHARED_W_PRIVATE	= 0x3;
	int RW_SHARED		= 0x4;

	int HEAP		= 0x5;

	int THREAD		= 0x6;

	int START_SIMULATION	= 0x8;
	int STOP_SIMULATION	= 0x9;
}

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #6: shared_counter.java --]
[-- Type: text/x-java; name="shared_counter.java", Size: 802 bytes --]

class shared_counter implements Runnable, do_options
{
	static int counter = 0;
	long thread_id;
	
	shared_counter(long thread_id)
	{
		this.thread_id = thread_id;
	}

	long get_thread_id()
	{
		return thread_id;
	}

	public void run()
	{
		custom.bind_this_thread(get_thread_id());
		custom.do_this(do_options.TX_BEGIN);
		counter++;
		custom.do_this(do_options.TX_COMMIT);
	}

	public static void main(String[]args)
	{
		Thread sc[] = new Thread[Integer.parseInt(args[0])];
		for(int i = 0;i<sc.length;i++)
		{
			sc[i] = new Thread(new shared_counter(i));
			sc[i].start();
		}

		for(int i = 0;i<sc.length;i++)
		{
			try
			{
				sc[i].join();
			}
			catch(Exception e)
			{
				System.out.println("Got the error "+e);
			}
			
		}
		System.out.println("shared counter value is "+counter);
	}
	
}

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #7: java_magic_c.h --]
[-- Type: text/x-chdr; name="java_magic_c.h", Size: 495 bytes --]

#ifndef JAVA_MAGIC_C_H_
#define JAVA_MAGIC_C_H_
/* use to allow c++ files to import it */
#ifdef __cplusplus
extern "C" {
#endif

#define	ABORT_TX		0xA
#define	BEGIN_TX		0xB
#define	COMMIT_TX		0xC
#define	PRINT_TX		0xD


#define MAGIC(n) do {                                \
  asm volatile ("movl %0, %%eax" : : "g" (n) : "eax");  \
  asm volatile ("xchg %bx,%bx");                        \
} while (0)

#define MAGIC_BREAKPOINT MAGIC(0)

#ifdef __cplusplus
}
#endif

#endif /*JAVA_MAGIC_C_*/


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2009-10-28 18:32 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-27  8:22 Create binary from GCJ generated assembly isuru herath
2009-10-27  9:42 ` Andrew Haley
2009-10-28 15:05   ` isuru herath
2009-10-28 15:22     ` Bryce McKinlay
2009-10-28 15:43       ` isuru herath
2009-10-28 15:56     ` Andrew Haley
2009-10-28 18:12 isuru herath
2009-10-28 18:32 ` Andrew Haley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).