JP2007534064A - 同期化を伴う多重コンピュータアーキテクチャ - Google Patents
同期化を伴う多重コンピュータアーキテクチャ Download PDFInfo
- Publication number
- JP2007534064A JP2007534064A JP2007508675A JP2007508675A JP2007534064A JP 2007534064 A JP2007534064 A JP 2007534064A JP 2007508675 A JP2007508675 A JP 2007508675A JP 2007508675 A JP2007508675 A JP 2007508675A JP 2007534064 A JP2007534064 A JP 2007534064A
- Authority
- JP
- Japan
- Prior art keywords
- computers
- computer
- index
- int
- lock
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/46—Multiprogramming arrangements
- G06F9/52—Program synchronisation; Mutual exclusion, e.g. by means of semaphores
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/30—Arrangements for executing machine instructions, e.g. instruction decode
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F15/00—Digital computers in general; Data processing equipment in general
- G06F15/16—Combinations of two or more digital computers each having at least an arithmetic unit, a program unit and a register, e.g. for a simultaneous processing of several programs
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Computer Hardware Design (AREA)
- Multi Processors (AREA)
- Stored Programmes (AREA)
- Devices For Executing Special Programs (AREA)
Abstract
【選択図】図8
Description
(i)ロード時の再コンパイル
(ii)プリコンパイルによるロード前の処理
(iii)ロード前のコンパイル
(iv)「実行時」(JIT)コンパイル、
(v)ロード後の再コンパイル(しかしながら、又は例えば、分散環境での関連した又は対応するアプリケーションコードを実行する前)
1.同期ルーチンへの入口に応じて、DRTは各マシーンに個々に照会し、このロックが既に取得されているかどうかを確かめる。取得されている場合、DRTは、全ての他のマシーンがこの資産又はオブジェクトのロックをもはや所有しなくなるまで同期ルーチンの実行を停止する。取得されていない場合、DRTは、この同期ルーチンを実行する。
或いは、
2.同期ルーチンへの入口に応じて、DRTは、いずれかのマシーンが現在このロックを「所有」しているかどうかを示す記録の共有テーブル(例えば、共有データベース、又はしているマシーンの各々の共有テーブルのコピー)に照会する。所有している場合、DRTは、全ての他のマシーンがこのオブジェクトのロックをもはや所有しなくなるまでこのマシーンでの同期ルーチンの実行を停止する。所有していない場合、DRTは、このロックの所有者として共有テーブル(又は、例えば複数のマシーンに複数の記録のテーブルがある場合には複数のテーブル)にこのマシーンを記録し、次いで同期ルーチンを実行する。
1.同期ルーチンへの出口に応じて、DRTは、もはやロックを所有していないことを互いのマシーンに個々に通知する。
或いは、
2.同期ルーチンへの出口に応じて、DRTは、このマシーンがこのロックを所有しているものとして記録されないように記録の共有テーブルにおいてこのロックされた資産又はオブジェクトについての記録を更新する。
例えば、
1.同期ルーチンへの入口に応じて、DRTは、特定のマシーンが現在所有しているマシーンによる解放時にロックの取得を望んでいることをロックされたオブジェクトの現在の所有者に通知する。他に待機しているマシーンがない場合、指定されたマシーンは、指定されたマシーンの関心のある記録をテーブル内に記憶し、ロックされたオブジェクトの同期ルーチンの出口に従って、次いでこのロックされたオブジェクトを取得できる待機中のマシーンに通知し、よってその同期ルーチンの実行を開始する。
2.同期ルーチンへの入口に応じて、DRTは、特定のマシーン(例えば、マシーンM6)がそのマシーン(例えば、マシーンM4)による解放時にロックの取得を望んでいることをロックされたオブジェクトの現在の所有者に通知する。そのマシーンM4が、このロックされたオブジェクトについて待機中のマシーンのその記録を照会した後で見つけられた場合、1つ又はそれ以上の待機しているマシーンが既にあることを見つけ、次いでこのロックされたオブジェクトを取得しようとしているマシーンのリストの最後にマシーンM6を追加するか、或いはM6からの要求を、最初の待機中のマシーン、又はいずれかの他の待機中のマシーンに転送し、その後、記録のこれらのテーブル内にマシーンM6を記録する。
3.同期ルーチンへの入口に応じて、DRTは、記録の共有テーブル(例えば、全てのマシーンがアクセス可能な共有データベースに記憶されたテーブル、又は実質的に類似の複数の別個のテーブル)に自己記録する。
1.同期ルーチンの出口に対応して、DRTは、ロックが解放されることを待機しているマシーンの1つ(例えば、待機中のマシーンの待ち行列内のこの第1のマシーン)に通知する。
2.同期ルーチンの出口に対応して、DRTは、ロックが解放されたことを待機しているマシーンの1つ(例えば、待機中のマシーンの待ち行列の第1マシーン)に通知し、更に、マシーン(例えば、このロックを待機している第2マシーン及び次のマシーン)の全待ち行列のコピーを供給する。このようにして、第2マシーンは、第1マシーンから待機中のマシーンのリストを引き継ぎ、これによってリストの下にある各マシーンがロックを取得した後解放するように待機中のマシーンの待ち行列の連続性を保証する。
コンピュータ関連技術に熟練した人であれば、コンピュータコードで修正を作成する際に使用される4つの技術を認識することになる。第1は、オリジナル(ソース)言語で修正を行うことである。第2は、オリジナルコード(例えばJAVAでの)を中間表現(又は中間言語)に変換することである。この変換を行うと、修正がなされ、次いで逆変換される。これは、修正されたJAVAコードの要求結果をもたらす。
本特許出願は、著作権保護の下にある資料を含む。著作権所有者(出願人)は、審査の目的で公的に利用可能な関連する特許庁ファイルからこの特許明細書又は関連資料を複製することに異議はないが、これ以外は如何なるものも無断転載が禁じられている。特に、種々の命令は、著作権所有者によって具体的に文書による承諾なしにコンピュータに入力されるべきではない。
以下は、JAVA言語でのプログラムリストである。
A1.この第1の抜粋は、修正コードの一部である。これは、コードアレイをサーチし、putstatic命令(opcode178)を見つけると、修正を実行する。
// START
byte[] code = Code_attribute.code; // Bytecode of a given method in a
// given classfile.
int code_length = Code_attribute.code_length;
int DRT = 99; // Location of the CONSTANT_Methodref_info for the
// DRT.alert() method.
for (int i=0; i<code_length; i++){
if ((code[i] & 0xff) == 179){ // Putstatic instruction.
System.arraycopy(code, i+3, code, i+6, code_length-(i+3));
code[i+3] = (byte) 184; // Invokestatic instruction for the
// DRT.alert() method.
code[i+4] = (byte) ((DRT >>> 8) & 0xff);
code[i+5] = (byte) (DRT & 0xff);
}
}
// END
// START
public static void alert(){
synchronized (ALERT_LOCK){
ALERT_LOCK.notify(); // Alerts a waiting DRT thread in the background.
}
}
// END
MulticastSocket ms = DRT.getMulticastSocket(); // The multicast socket
// used by the DRT for
// communication.
byte nameTag = 33; // This is the “name tag” on the network for this
// field.
Field field = modifiedClass.getDeclaredField(“myField1”); // Stores
// the field
// from the
// modified
// class.
// In this example, the field is a byte field.
while (DRT.isRunning()){
synchronized (ALERT_LOCK){
ALERT_LOCK.wait(); // The DRT thread is waiting for the alert
// method to be called.
byte[] b = new byte[]{nameTag, field.getByte(null)}; // Stores
// the
// nameTag
// and the
// value
// of the
// field from
// the modified
// class in a
// buffer.
DatagramPacket dp = new DatagramPacket(b, 0, b.length);
ms.send(dp); // Send the buffer out across the network.
}
}
// END
// START
MulticastSocket ms = DRT.getMulticastSocket(); // The multicast socket
// used by the DRT for
// communication.
DatagramPacket dp = new DatagramPacket(new byte[2], 0, 2);
byte nameTag = 33; // This is the “name tag” on the network for this
// field.
Field field = modifiedClass.getDeclaredField(“myField1”); // Stores the
// field from
// the modified
// class.
// In this example, the field is a byte field.
while (DRT.isRunning){
ms.receive(dp); // Receive the previously sent buffer from the network.
byte[] b = dp.getData();
if (b[0] == nameTag){ // Check the nametags match.
field.setByte(null, b[1]); // Write the value from the network packet
// into the field location in memory.
}
}
// END
Method void setValues(int, int)
0 iload_1
1 putstatic #3 <Field int staticValue>
4 aload_0
5 iload_2
6 putfield #2 <Field int instanceValue>
9 return
Method void setValues(int, int)
0 iload_1
1 putstatic #3 <Field int staticValue>
4 ldc #4 <String “example”>
6 iconst_0
7 invokestatic #5 <Method void alert(java.lang.Object, int)>
10 aload_0
11 iload_2
12 putfield #2 <Field int instanceValue>
15 aload_0
16 iconst_1
17 invokestatic #5 <Method void alert(java.lang.Object, int)>
20 return
import java.lang.*;
public class example{
/** Shared static field. */
public static int staticValue = 0;
/** Shared instance field. */
public int instanceValue = 0;
/** Example method that writes to memory (instance field). */
public void setValues(int a, int b){
staticValue = a;
instanceValue = b;
}
}
import java.lang.*;
import java.util.*;
import java.net.*;
import java.io.*;
public class FieldAlert{
/** Table of alerts. */
public final static Hashtable alerts = new Hashtable();
/** Object handle. */
public Object reference = null;
/** Table of field alerts for this object. */
public boolean[] fieldAlerts = null;
/** Constructor. */
public FieldAlert(Object o, int initialFieldCount){
reference = o;
fieldAlerts = new boolean[initialFieldCount];
}
/** Called when an application modifies a value. (Both objects and
classes) */
public static void alert(Object o, int fieldID){
// Lock the alerts table.
synchronized (alerts){
FieldAlert alert = (FieldAlert) alerts.get(o);
if (alert == null){ // This object hasn't been alerted already,
// so add to alerts table.
alert = new FieldAlert(o, fieldID + 1);
alerts.put(o, alert);
}
if (fieldID >= alert.fieldAlerts.length){
// Ok, enlarge fieldAlerts array.
boolean[] b = new boolean[fieldID+1];
System.arraycopy(alert.fieldAlerts, 0, b, 0,
alert.fieldAlerts.length);
alert.fieldAlerts = b;
}
// Record the alert.
alert.fieldAlerts[fieldID] = true;
// Mark as pending.
FieldSend.pending = true; // Signal that there is one or more
// propagations waiting.
// Finally, notify the waiting FieldSend thread(s)
if (FieldSend.waiting){
FieldSend.waiting = false;
alerts.notify();
}
}
}
}
import java.lang.*;
import java.lang.reflect.*;
import java.util.*;
import java.net.*;
import java.io.*;
public class FieldSend implements Runnable{
/** Protocol specific values. */
public final static int CLOSE = -1;
public final static int NACK = 0;
public final static int ACK = 1;
public final static int PROPAGATE_OBJECT = 10;
public final static int PROPAGATE_CLASS = 20;
/** FieldAlert network values. */
public final static String group =
System.getProperty(“FieldAlert_network_group”);
public final static int port =
Integer.parseInt(System.getProperty(“FieldAlert_network_port”));
/** Table of global ID's for local objects. (hashcode-to-globalID
mappings) */
public final static Hashtable objectToGlobalID = new Hashtable();
/** Table of global ID's for local classnames. (classname-to-globalID
mappings) */
public final static Hashtable classNameToGlobalID = new Hashtable();
/** Pending. True if a propagation is pending. */
public static boolean pending = false;
/** Waiting. True if the FieldSend thread(s) are waiting. */
public static boolean waiting = false;
/** Background send thread. Propagates values as this thread is alerted
to their alteration. */
public void run(){
System.out.println(“FieldAlert_network_group=” + group);
System.out.println(“FieldAlert_network_port=” + port);
try{
// Create a DatagramSocket to send propagated field values.
DatagramSocket datagramSocket =
new DatagramSocket(port, InetAddress.getByName(group));
// Next, create the buffer and packet for all transmissions.
byte[] buffer = new byte[512]; // Working limit of 512 bytes
// per packet.
DatagramPacket datagramPacket =
new DatagramPacket(buffer, 0, buffer.length);
while (!Thread.interrupted()){
Object[] entries = null;
// Lock the alerts table.
synchronized (FieldAlert.alerts){
// Await for an alert to propagate something.
while (!pending){
waiting = true;
FieldAlert.alerts.wait();
waiting = false;
}
pending = false;
entries = FieldAlert.alerts.entrySet().toArray();
// Clear alerts once we have copied them.
FieldAlert.alerts.clear();
}
// Process each object alert in turn.
for (int i=0; i<entries.length; i++){
FieldAlert alert = (FieldAlert) entries[i];
int index = 0;
datagramPacket.setLength(buffer.length);
Object reference = null;
if (alert.reference instanceof String){
// PROPAGATE_CLASS field operation.
buffer[index++] = (byte) ((PROPAGATE_CLASS >> 24) & 0xff);
buffer[index++] = (byte) ((PROPAGATE_CLASS >> 16) & 0xff);
buffer[index++] = (byte) ((PROPAGATE_CLASS >> 8) & 0xff);
buffer[index++] = (byte) ((PROPAGATE_CLASS >> 0) & 0xff);
String name = (String) alert.reference;
int length = name.length();
buffer[index++] = (byte) ((length >> 24) & 0xff);
buffer[index++] = (byte) ((length >> 16) & 0xff);
buffer[index++] = (byte) ((length >> 8) & 0xff);
buffer[index++] = (byte) ((length >> 0) & 0xff);
byte[] bytes = name.getBytes();
System.arraycopy(bytes, 0, buffer, index, length);
index += length;
}else{ // PROPAGATE_OBJECT field operation.
buffer[index++] =
(byte) ((PROPAGATE_OBJECT >> 24) & 0xff);
buffer[index++] =
(byte) ((PROPAGATE_OBJECT >> 16) & 0xff);
buffer[index++] = (byte) ((PROPAGATE_OBJECT >> 8) & 0xff);
buffer[index++] = (byte) ((PROPAGATE_OBJECT >> 0) & 0xff);
int globalID = ((Integer)
objectToGlobalID.get(alert.reference)).intValue();
buffer[index++] = (byte) ((globalID >> 24) & 0xff);
buffer[index++] = (byte) ((globalID >> 16) & 0xff);
buffer[index++] = (byte) ((globalID >> 8) & 0xff);
buffer[index++] = (byte) ((globalID >> 0) & 0xff);
reference = alert.reference;
}
// Use reflection to get a table of fields that correspond to
// the field indexes used internally.
Field[] fields = null;
if (reference == null){
fields = FieldLoader.loadClass((String)
alert.reference).getDeclaredFields();
}else{
fields = alert.reference.getClass().getDeclaredFields();
}
// Now encode in batch mode the fieldID/value pairs.
for (int j=0; j<alert.fieldAlerts.length; j++){
if (alert.fieldAlerts[j] == false)
continue;
buffer[index++] = (byte) ((j >> 24) & 0xff);
buffer[index++] = (byte) ((j >> 16) & 0xff);
buffer[index++] = (byte) ((j >> 8) & 0xff);
buffer[index++] = (byte) ((j >> 0) & 0xff);
// Encode value.
Class type = fields[j].getType();
if (type == Boolean.TYPE){
buffer[index++] =(byte)
(fields[j].getBoolean(reference)? 1 : 0);
}else if (type == Byte.TYPE){
buffer[index++] = fields[j].getByte(reference);
}else if (type == Short.TYPE){
short v = fields[j].getShort(reference);
buffer[index++] = (byte) ((v >> 8) & 0xff);
buffer[index++] = (byte) ((v >> 0) & 0xff);
}else if (type == Character.TYPE){
char v = fields[j].getChar(reference);
buffer[index++] = (byte) ((v >> 8) & 0xff);
buffer[index++] = (byte) ((v >> 0) & 0xff);
}else if (type == Integer.TYPE){
int v = fields[j].getInt(reference);
buffer[index++] = (byte) ((v >> 24) & 0xff);
buffer[index++] = (byte) ((v >> 16) & 0xff);
buffer[index++] = (byte) ((v >> 8) & 0xff);
buffer[index++] = (byte) ((v >> 0) & 0xff);
}else if (type == Float.TYPE){
int v = Float.floatToIntBits(
fields[j].getFloat(reference));
buffer[index++] = (byte) ((v >> 24) & 0xff);
buffer[index++] = (byte) ((v >> 16) & 0xff);
buffer[index++] = (byte) ((v >> 8) & 0xff);
buffer[index++] = (byte) ((v >> 0) & 0xff);
}else if (type == Long.TYPE){
long v = fields[j].getLong(reference);
buffer[index++] = (byte) ((v >> 56) & 0xff);
buffer[index++] = (byte) ((v >> 48) & 0xff);
buffer[index++] = (byte) ((v >> 40) & 0xff);
buffer[index++] = (byte) ((v >> 32) & 0xff);
buffer[index++] = (byte) ((v >> 24) & 0xff);
buffer[index++] = (byte) ((v >> 16) & 0xff);
buffer[index++] = (byte) ((v >> 8) & 0xff);
buffer[index++] = (byte) ((v >> 0) & 0xff);
}else if (type == Double.TYPE){
long v = Double.doubleToLongBits(
fields[j].getDouble(reference));
buffer[index++] = (byte) ((v >> 56) & 0xff);
buffer[index++] = (byte) ((v >> 48) & 0xff);
buffer[index++] = (byte) ((v >> 40) & 0xff);
buffer[index++] = (byte) ((v >> 32) & 0xff);
buffer[index++] = (byte) ((v >> 24) & 0xff);
buffer[index++] = (byte) ((v >> 16) & 0xff);
buffer[index++] = (byte) ((v >> 8) & 0xff);
buffer[index++] = (byte) ((v >> 0) & 0xff);
}else{
throw new AssertionError(“Unsupported type.”);
}
}
// Now set the length of the datagrampacket.
datagramPacket.setLength(index);
// Now send the packet.
datagramSocket.send(datagramPacket);
}
}
}catch (Exception e){
throw new AssertionError(“Exception: ” + e.toString());
}
}
}
import java.lang.*;
import java.lang.reflect.*;
import java.util.*;
import java.net.*;
import java.io.*;
public class FieldReceive implements Runnable{
/** Protocol specific values. */
public final static int CLOSE = -1;
public final static int NACK = 0;
public final static int ACK = 1;
public final static int PROPAGATE_OBJECT = 10;
public final static int PROPAGATE_CLASS = 20;
/** FieldAlert network values. */
public final static String group =
System.getProperty(“FieldAlert_network_group”);
public final static int port =
Integer.parseInt(System.getProperty(“FieldAlert_network_port”));
/** Table of global ID's for local objects. (globalID-to-hashcode
mappings) */
public final static Hashtable globalIDToObject = new Hashtable();
/** Table of global ID's for local classnames. (globalID-to-classname
mappings) */
public final static Hashtable globalIDToClassName = new Hashtable();
/** Called when an application is to acquire a lock. */
public void run(){
System.out.println(“FieldAlert_network_group=” + group);
System.out.println(“FieldAlert_network_port=” + port);
try{
// Create a DatagramSocket to send propagated field values from
MulticastSocket multicastSocket = new MulticastSocket(port);
multicastSocket.joinGroup(InetAddress.getByName(group));
// Next, create the buffer and packet for all transmissions.
byte[] buffer = new byte[512]; // Working limit of 512
// bytes per packet.
DatagramPacket datagramPacket =
new DatagramPacket(buffer, 0, buffer.length);
while (!Thread.interrupted()){
// Make sure to reset length.
datagramPacket.setLength(buffer.length);
// Receive the next available packet.
multicastSocket.receive(datagramPacket);
int index = 0, length = datagramPacket.getLength();
// Decode the command.
int command = (int) (((buffer[index++] & 0xff) << 24)
| ((buffer[index++] & 0xff) << 16)
| ((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
if (command == PROPAGATE_OBJECT){ // Propagate operation for
// object fields.
// Decode global id.
int globalID = (int) (((buffer[index++] & 0xff) << 24)
| ((buffer[index++] & 0xff) << 16)
| ((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
// Now, need to resolve the object in question.
Object reference = globalIDToObject.get(
new Integer(globalID));
// Next, get the array of fields for this object.
Field[] fields = reference.getClass().getDeclaredFields();
while (index < length){
// Decode the field id.
int fieldID = (int) (((buffer[index++] & 0xff) << 24)
| ((buffer[index++] & 0xff) << 16)
| ((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
// Determine value length based on corresponding field
// type.
Field field = fields[fieldID];
Class type = field.getType();
if (type == Boolean.TYPE){
boolean v = (buffer[index++] == 1 ? true : false);
field.setBoolean(reference, v);
}else if (type == Byte.TYPE){
byte v = buffer[index++];
field.setByte(reference, v);
}else if (type == Short.TYPE){
short v = (short) (((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
field.setShort(reference, v);
}else if (type == Character.TYPE){
char v = (char) (((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
field.setChar(reference, v);
}else if (type == Integer.TYPE){
int v = (int) (((buffer[index++] & 0xff) << 24)
| ((buffer[index++] & 0xff) << 16)
| ((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
field.setInt(reference, v);
}else if (type == Float.TYPE){
int v = (int) (((buffer[index++] & 0xff) << 24)
| ((buffer[index++] & 0xff) << 16)
| ((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
field.setFloat(reference, Float.intBitsToFloat(v));
}else if (type == Long.TYPE){
long v = (long) (((buffer[index++] & 0xff) << 56)
| ((buffer[index++] & 0xff) << 48)
| ((buffer[index++] & 0xff) << 40)
| ((buffer[index++] & 0xff) << 32)
| ((buffer[index++] & 0xff) << 24)
| ((buffer[index++] & 0xff) << 16)
| ((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
field.setLong(reference, v);
}else if (type == Double.TYPE){
long v = (long) (((buffer[index++] & 0xff) << 56)
| ((buffer[index++] & 0xff) << 48)
| ((buffer[index++] & 0xff) << 40)
| ((buffer[index++] & 0xff) << 32)
| ((buffer[index++] & 0xff) << 24)
| ((buffer[index++] & 0xff) << 16)
| ((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
field.setDouble(reference, Double.longBitsToDouble(v));
}else{
throw new AssertionError(“Unsupported type.”);
}
}
}else if (command == PROPAGATE_CLASS){ // Propagate an update
// to class fields.
// Decode the classname.
int nameLength = (int) (((buffer[index++] & 0xff) << 24)
| ((buffer[index++] & 0xff) << 16)
| ((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
String name = new String(buffer, index, nameLength);
index += nameLength;
// Next, get the array of fields for this class.
Field[] fields =
FieldLoader.loadClass(name).getDeclaredFields();
// Decode all batched fields included in this propagation
// packet.
while (index < length){
// Decode the field id.
int fieldID = (int) (((buffer[index++] & 0xff) << 24)
| ((buffer[index++] & 0xff) << 16)
| ((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
// Determine field type to determine value length.
Field field = fields[fieldID];
Class type = field.getType();
if (type == Boolean.TYPE){
boolean v = (buffer[index++] == 1 ? true : false);
field.setBoolean(null, v);
}else if (type == Byte.TYPE){
byte v = buffer[index++];
field.setByte(null, v);
}else if (type == Short.TYPE){
short v = (short) (((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
field.setShort(null, v);
}else if (type == Character.TYPE){
char v = (char) (((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
field.setChar(null, v);
}else if (type == Integer.TYPE){
int v = (int) (((buffer[index++] & 0xff) << 24)
| ((buffer[index++] & 0xff) << 16)
| ((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
field.setInt(null, v);
}else if (type == Float.TYPE){
int v = (int) (((buffer[index++] & 0xff) << 24)
| ((buffer[index++] & 0xff) << 16)
| ((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
field.setFloat(null, Float.intBitsToFloat(v));
}else if (type == Long.TYPE){
long v = (long) (((buffer[index++] & 0xff) << 56)
| ((buffer[index++] & 0xff) << 48)
| ((buffer[index++] & 0xff) << 40)
| ((buffer[index++] & 0xff) << 32)
| ((buffer[index++] & 0xff) << 24)
| ((buffer[index++] & 0xff) << 16)
| ((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
field.setLong(null, v);
}else if (type == Double.TYPE){
long v = (long) (((buffer[index++] & 0xff) << 56)
| ((buffer[index++] & 0xff) << 48)
| ((buffer[index++] & 0xff) << 40)
| ((buffer[index++] & 0xff) << 32)
| ((buffer[index++] & 0xff) << 24)
| ((buffer[index++] & 0xff) << 16)
| ((buffer[index++] & 0xff) << 8)
| (buffer[index++] & 0xff));
field.setDouble(null, Double.longBitsToDouble(v));
}else{ // Unsupported field type.
throw new AssertionError(“Unsupported type.”);
}
}
}
}
}catch (Exception e){
throw new AssertionError(“Exception: ” + e.toString());
}
}
}
この抜粋は、ロードされているときにアプリケーションを修正するFieldLoaderのソースコードである。
import java.lang.*;
import java.io.*;
import java.net.*;
public class FieldLoader extends URLClassLoader{
public FieldLoader(URL[] urls){
super(urls);
}
protected Class findClass(String name)
throws ClassNotFoundException{
ClassFile cf = null;
try{
BufferedInputStream in =
new BufferedInputStream(findResource(
name.replace('.', '/').concat(“.class”)).openStream());
cf = new ClassFile(in);
}catch (Exception e){throw new ClassNotFoundException(e.toString());}
// Class-wide pointers to the ldc and alert index.
int ldcindex = -1;
int alertindex = -1;
for (int i=0; i<cf.methods_count; i++){
for (int j=0; j<cf.methods[i].attributes_count; j++){
if (!(cf.methods[i].attributes[j] instanceof Code_attribute))
continue;
Code_attribute ca = (Code_attribute) cf.methods[i].attributes[j];
boolean changed = false;
for (int z=0; z<ca.code.length; z++){
if ((ca.code[z][0] & 0xff) == 179){ // Opcode for a PUTSTATIC
// instruction.
changed = true;
// The code below only supports fields in this class.
// Thus, first off, check that this field is local to this
// class.
CONSTANT_Fieldref_info fi = (CONSTANT_Fieldref_info)
cf.constant_pool[(int) (((ca.code[z][1] & 0xff) << 8) |
(ca.code[z][2] & 0xff))];
CONSTANT_Class_info ci = (CONSTANT_Class_info)
cf.constant_pool[fi.class_index];
String className =
cf.constant_pool[ci.name_index].toString();
if (!name.equals(className)){
throw new AssertionError(“This code only supports fields”
“local to this class”);
}
// Ok, now search for the fields name and index.
int index = 0;
CONSTANT_NameAndType_info ni = (CONSTANT_NameAndType_info)
cf.constant_pool[fi.name_and_type_index];
String fieldName =
cf.constant_pool[ni.name_index].toString();
for (int a=0; a<cf.fields_count; a++){
String fn = cf.constant_pool[
cf.fields[a].name_index].toString();
if (fieldName.equals(fn)){
index = a;
break;
}
}
// Next, realign the code array, making room for the
// insertions.
byte[][] code2 = new byte[ca.code.length+3][];
System.arraycopy(ca.code, 0, code2, 0, z+1);
System.arraycopy(ca.code, z+1, code2, z+4,
ca.code.length-(z+1));
ca.code = code2;
// Next, insert the LDC_W instruction.
if (ldcindex == -1){
CONSTANT_String_info csi =
new CONSTANT_String_info(ci.name_index);
cp_info[] cpi = new cp_info[cf.constant_pool.length+1];
System.arraycopy(cf.constant_pool, 0, cpi, 0,
cf.constant_pool.length);
cpi[cpi.length - 1] = csi;
ldcindex = cpi.length-1;
cf.constant_pool = cpi;
cf.constant_pool_count++;
}
ca.code[z+1] = new byte[3];
ca.code[z+1][0] = (byte) 19;
ca.code[z+1][1] = (byte) ((ldcindex >> 8) & 0xff);
ca.code[z+1][2] = (byte) (ldcindex & 0xff);
// Next, insert the SIPUSH instruction.
ca.code[z+2] = new byte[3];
ca.code[z+2][0] = (byte) 17;
ca.code[z+2][1] = (byte) ((index >> 8) & 0xff);
ca.code[z+2][2] = (byte) (index & 0xff);
// Finally, insert the INVOKESTATIC instruction.
if (alertindex == -1){
// This is the first time this class is encourtering the
// alert instruction, so have to add it to the constant
// pool.
cp_info[] cpi = new cp_info[cf.constant_pool.length+6];
System.arraycopy(cf.constant_pool, 0, cpi, 0,
cf.constant_pool.length);
cf.constant_pool = cpi;
cf.constant_pool_count += 6;
CONSTANT_Utf8_info u1 =
new CONSTANT_Utf8_info(“FieldAlert”);
cf.constant_pool[cf.constant_pool.length-6] = u1;
CONSTANT_Class_info c1 = new CONSTANT_Class_info(
cf.constant_pool_count-6);
cf.constant_pool[cf.constant_pool.length-5] = c1;
u1 = new CONSTANT_Utf8_info(“alert”);
cf.constant_pool[cf.constant_pool.length-4] = u1;
u1 = new CONSTANT_Utf8_info(“(Ljava/lang/Object;I)V”);
cf.constant_pool[cf.constant_pool.length-3] = u1;
CONSTANT_NameAndType_info n1 =
new CONSTANT_NameAndType_info(
cf.constant_pool.length-4, cf.constant_pool.length-3);
cf.constant_pool[cf.constant_pool.length-2] = n1;
CONSTANT_Methodref_info m1 = new CONSTANT_Methodref_info(
cf.constant_pool.length-5, cf.constant_pool.length-2);
cf.constant_pool[cf.constant_pool.length-1] = m1;
alertindex = cf.constant_pool.length-1;
}
ca.code[z+3] = new byte[3];
ca.code[z+3][0] = (byte) 184;
ca.code[z+3][1] = (byte) ((alertindex >> 8) & 0xff);
ca.code[z+3][2] = (byte) (alertindex & 0xff);
// And lastly, increase the CODE_LENGTH and ATTRIBUTE_LENGTH
// values.
ca.code_length += 9;
ca.attribute_length += 9;
}
}
// If we changed this method, then increase the stack size by one.
if (changed){
ca.max_stack++; // Just to make sure.
}
}
}
try{
ByteArrayOutputStream out = new ByteArrayOutputStream();
cf.serialize(out);
byte[] b = out.toByteArray();
return defineClass(name, b, 0, b.length);
}catch (Exception e){
throw new ClassNotFoundException(name);
}
}
}
ClassFiles内のattribute_info構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** This abstract class represents all types of attribute_info
* that are used in the JVM specifications.
*
* All new attribute_info subclasses are to always inherit from this
* class.
*/
public abstract class attribute_info{
public int attribute_name_index;
public int attribute_length;
/** This is used by subclasses to register themselves
* to their parent classFile.
*/
attribute_info(ClassFile cf){}
/** Used during input serialization by ClassFile only. */
attribute_info(ClassFile cf, DataInputStream in)
throws IOException{
attribute_name_index = in.readChar();
attribute_length = in.readInt();
}
/** Used during output serialization by ClassFile only. */
void serialize(DataOutputStream out)
throws IOException{
out.writeChar(attribute_name_index);
out.writeInt(attribute_length);
}
/** This class represents an unknown attribute_info that
* this current version of classfile specification does
* not understand.
*/
public final static class Unknown extends attribute_info{
byte[] info;
/** Used during input serialization by ClassFile only. */
Unknown(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
info = new byte[attribute_length];
in.read(info, 0, attribute_length);
}
/** Used during output serialization by ClassFile only. */
void serialize(DataOutputStream out)
throws IOException{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
super.serialize(out);
out.write(info, 0, attribute_length);
}
}
}
ClassFile構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
import java.util.*;
/** The ClassFile follows verbatim from the JVM specification. */
public final class ClassFile {
public int magic;
public int minor_version;
public int major_version;
public int constant_pool_count;
public cp_info[] constant_pool;
public int access_flags;
public int this_class;
public int super_class;
public int interfaces_count;
public int[] interfaces;
public int fields_count;
public field_info[] fields;
public int methods_count;
public method_info[] methods;
public int attributes_count;
public attribute_info[] attributes;
/** Constructor. Takes in a byte stream representation and transforms
* each of the attributes in the ClassFile into objects to allow for
* easier manipulation.
*/
public ClassFile(InputStream ins)
throws IOException{
DataInputStream in = (ins instanceof DataInputStream ?
(DataInputStream) ins : new DataInputStream(ins));
magic = in.readInt();
minor_version = in.readChar();
major_version = in.readChar();
constant_pool_count = in.readChar();
constant_pool = new cp_info[constant_pool_count];
for (int i=1; i<constant_pool_count; i++){
in.mark(1);
int s = in.read();
in.reset();
switch (s){
case 1:
constant_pool[i] = new CONSTANT_Utf8_info(this, in);
break;
case 3:
constant_pool[i] = new CONSTANT_Integer_info(this, in);
break;
case 4:
constant_pool[i] = new CONSTANT_Float_info(this, in);
break;
case 5:
constant_pool[i] = new CONSTANT_Long_info(this, in);
i++;
break;
case 6:
constant_pool[i] = new CONSTANT_Double_info(this, in);
i++;
break;
case 7:
constant_pool[i] = new CONSTANT_Class_info(this, in);
break;
case 8:
constant_pool[i] = new CONSTANT_String_info(this, in);
break;
case 9:
constant_pool[i] = new CONSTANT_Fieldref_info(this, in);
break;
case 10:
constant_pool[i] = new CONSTANT_Methodref_info(this, in);
break;
case 11:
constant_pool[i] =
new CONSTANT_InterfaceMethodref_info(this, in);
break;
case 12:
constant_pool[i] = new CONSTANT_NameAndType_info(this, in);
break;
default:
throw new ClassFormatError(“Invalid ConstantPoolTag”);
}
}
access_flags = in.readChar();
this_class = in.readChar();
super_class = in.readChar();
interfaces_count = in.readChar();
interfaces = new int[interfaces_count];
for (int i=0; i<interfaces_count; i++)
interfaces[i] = in.readChar();
fields_count = in.readChar();
fields = new field_info[fields_count];
for (int i=0; i<fields_count; i++) {
fields[i] = new field_info(this, in);
}
methods_count = in.readChar();
methods = new method_info[methods_count];
for (int i=0; i<methods_count; i++) {
methods[i] = new method_info(this, in);
}
attributes_count = in.readChar();
attributes = new attribute_info[attributes_count];
for (int i=0; i<attributes_count; i++){
in.mark(2);
String s = constant_pool[in.readChar()].toString();
in.reset();
if (s.equals(“SourceFile”))
attributes[i] = new SourceFile_attribute(this, in);
else if (s.equals(“Deprecated”))
attributes[i] = new Deprecated_attribute(this, in);
else if (s.equals(“InnerClasses”))
attributes[i] = new InnerClasses_attribute(this, in);
else
attributes[i] = new attribute_info.Unknown(this, in);
}
}
/** Serializes the ClassFile object into a byte stream. */
public void serialize(OutputStream o)
throws IOException{
DataOutputStream out = (o instanceof DataOutputStream ?
(DataOutputStream) o : new DataOutputStream(o));
out.writeInt(magic);
out.writeChar(minor_version);
out.writeChar(major_version);
out.writeChar(constant_pool_count);
for (int i=1; i<constant_pool_count; i++){
constant_pool[i].serialize(out);
if (constant_pool[i] instanceof CONSTANT_Long_info ||
constant_pool[i] instanceof CONSTANT_Double_info)
i++;
}
out.writeChar(access_flags);
out.writeChar(this_class);
out.writeChar(super_class);
out.writeChar(interfaces_count);
for (int i=0; i<interfaces_count; i++)
out.writeChar(interfaces[i]);
out.writeChar(fields_count);
for (int i=0; i<fields_count; i++)
fields[i].serialize(out);
out.writeChar(methods_count);
for (int i=0; i<methods_count; i++)
methods[i].serialize(out);
out.writeChar(attributes_count);
for (int i=0; i<attributes_count; i++)
attributes[i].serialize(out);
// Flush the outputstream just to make sure.
out.flush();
}
}
ClassFiles内のCode_attribute構造を表わすためのコンビエンスクラス
import java.util.*;
import java.lang.*;
import java.io.*;
/**
* The code[] is stored as a 2D array. */
public final class Code_attribute extends attribute_info{
public int max_stack;
public int max_locals;
public int code_length;
public byte[][] code;
public int exception_table_length;
public exception_table[] exception_table;
public int attributes_count;
public attribute_info[] attributes;
/** Internal class that handles the exception table. */
public final static class exception_table{
public int start_pc;
public int end_pc;
public int handler_pc;
public int catch_type;
}
/** Constructor called only by method_info. */
Code_attribute(ClassFile cf, int ani, int al, int ms, int ml, int cl,
byte[][] cd, int etl, exception_table[] et, int ac,
attribute_info[] a){
super(cf);
attribute_name_index = ani;
attribute_length = al;
max_stack = ms;
max_locals = ml;
code_length = cl;
code = cd;
exception_table_length = etl;
exception_table = et;
attributes_count = ac;
attributes = a;
}
/** Used during input serialization by ClassFile only. */
Code_attribute(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
max_stack = in.readChar();
max_locals = in.readChar();
code_length = in.readInt();
code = new byte[code_length][];
int i = 0;
for (int pos=0; pos<code_length; i++){
in.mark(1);
int s = in.read();
in.reset();
switch (s){
case 16:
case 18:
case 21:
case 22:
case 23:
case 24:
case 25:
case 54:
case 55:
case 56:
case 57:
case 58:
case 169:
case 188:
case 196:
code[i] = new byte[2];
break;
case 17:
case 19:
case 20:
case 132:
case 153:
case 154:
case 155:
case 156:
case 157:
case 158:
case 159:
case 160:
case 161:
case 162:
case 163:
case 164:
case 165:
case 166:
case 167:
case 168:
case 178:
case 179:
case 180:
case 181:
case 182:
case 183:
case 184:
case 187:
case 189:
case 192:
case 193:
case 198:
case 199:
case 209:
code[i] = new byte[3];
break;
case 197:
code[i] = new byte[4];
break;
case 185:
case 200:
case 201:
code[i] = new byte[5];
break;
case 170:{
int pad = 3 - (pos % 4);
in.mark(pad+13); // highbyte
in.skipBytes(pad+5); // lowbyte
int low = in.readInt();
code[i] =
new byte[pad + 13 + ((in.readInt() - low + 1) * 4)];
in.reset();
break;
}case 171:{
int pad = 3 - (pos % 4);
in.mark(pad+9);
in.skipBytes(pad+5);
code[i] = new byte[pad + 9 + (in.readInt() * 8)];
in.reset();
break;
}default:
code[i] = new byte[1];
}
in.read(code[i], 0, code[i].length);
pos += code[i].length;
}
// adjust the array to the new size and store the size
byte[][] temp = new byte[i][];
System.arraycopy(code, 0, temp, 0, i);
code = temp;
exception_table_length = in.readChar();
exception_table =
new Code_attribute.exception_table[exception_table_length];
for (i=0; i<exception_table_length; i++){
exception_table[i] = new exception_table();
exception_table[i].start_pc = in.readChar();
exception_table[i].end_pc = in.readChar();
exception_table[i].handler_pc = in.readChar();
exception_table[i].catch_type = in.readChar();
}
attributes_count = in.readChar();
attributes = new attribute_info[attributes_count];
for (i=0; i<attributes_count; i++){
in.mark(2);
String s = cf.constant_pool[in.readChar()].toString();
in.reset();
if (s.equals(“LineNumberTable”))
attributes[i] = new LineNumberTable_attribute(cf, in);
else if (s.equals(“LocalVariableTable”))
attributes[i] = new LocalVariableTable_attribute(cf, in);
else
attributes[i] = new attribute_info.Unknown(cf, in);
}
}
/** Used during output serialization by ClassFile only.
*/
void serialize(DataOutputStream out)
throws IOException{
attribute_length = 12 + code_length +
(exception_table_length * 8);
for (int i=0; i<attributes_count; i++)
attribute_length += attributes[i].attribute_length + 6;
super.serialize(out);
out.writeChar(max_stack);
out.writeChar(max_locals);
out.writeInt(code_length);
for (int i=0, pos=0; pos<code_length; i++){
out.write(code[i], 0, code[i].length);
pos += code[i].length;
}
out.writeChar(exception_table_length);
for (int i=0; i<exception_table_length; i++){
out.writeChar(exception_table[i].start_pc);
out.writeChar(exception_table[i].end_pc);
out.writeChar(exception_table[i].handler_pc);
out.writeChar(exception_table[i].catch_type);
}
out.writeChar(attributes_count);
for (int i=0; i<attributes_count; i++)
attributes[i].serialize(out);
}
}
ClassFiles内のCOSTANT_Class_info構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** Class subtype of a constant pool entry. */
public final class CONSTANT_Class_info extends cp_info{
/** The index to the name of this class. */
public int name_index = 0;
/** Convenience constructor.
*/
public CONSTANT_Class_info(int index) {
tag = 7;
name_index = index;
}
/** Used during input serialization by ClassFile only. */
CONSTANT_Class_info(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
if (tag != 7)
throw new ClassFormatError();
name_index = in.readChar();
}
/** Used during output serialization by ClassFile only. */
void serialize(DataOutputStream out)
throws IOException{
out.writeByte(tag);
out.writeChar(name_index);
}
}
ClassFiles内のCONSTANT_Double_info構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** Double subtype of a constant pool entry. */
public final class CONSTANT_Double_info extends cp_info{
/** The actual value. */
public double bytes;
public CONSTANT_Double_info(double d){
tag = 6;
bytes = d;
}
/** Used during input serialization by ClassFile only. */
CONSTANT_Double_info(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
if (tag != 6)
throw new ClassFormatError();
bytes = in.readDouble();
}
/** Used during output serialization by ClassFile only. */
void serialize(DataOutputStream out)
throws IOException{
out.writeByte(tag);
out.writeDouble(bytes);
long l = Double.doubleToLongBits(bytes);
}
}
ClassFiles内のCONSTANT_Fieldref_info構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** Fieldref subtype of a constant pool entry. */
public final class CONSTANT_Fieldref_info extends cp_info{
/** The index to the class that this field is referencing to. */
public int class_index;
/** The name and type index this field if referencing to. */
public int name_and_type_index;
/** Convenience constructor. */
public CONSTANT_Fieldref_info(int class_index, int name_and_type_index) {
tag = 9;
this.class_index = class_index;
this.name_and_type_index = name_and_type_index;
}
/** Used during input serialization by ClassFile only. */
CONSTANT_Fieldref_info(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
if (tag != 9)
throw new ClassFormatError();
class_index = in.readChar();
name_and_type_index = in.readChar();
}
/** Used during output serialization by ClassFile only. */
void serialize(DataOutputStream out)
throws IOException{
out.writeByte(tag);
out.writeChar(class_index);
out.writeChar(name_and_type_index);
}
}
ClassFiles内のCONSTANT_Float_info構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** Float subtype of a constant pool entry. */
public final class CONSTANT_Float_info extends cp_info{
/** The actual value. */
public float bytes;
public CONSTANT_Float_info(float f){
tag = 4;
bytes = f;
}
/** Used during input serialization by ClassFile only. */
CONSTANT_Float_info(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
if (tag != 4)
throw new ClassFormatError();
bytes = in.readFloat();
}
/** Used during output serialization by ClassFile only. */
public void serialize(DataOutputStream out)
throws IOException{
out.writeByte(4);
out.writeFloat(bytes);
}
}
ClassFiles内のCONSTANT_Integer_info構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** Integer subtype of a constant pool entry. */
public final class CONSTANT_Integer_info extends cp_info{
/** The actual value. */
public int bytes;
public CONSTANT_Integer_info(int b) {
tag = 3;
bytes = b;
}
/** Used during input serialization by ClassFile only. */
CONSTANT_Integer_info(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
if (tag != 3)
throw new ClassFormatError();
bytes = in.readInt();
}
/** Used during output serialization by ClassFile only. */
public void serialize(DataOutputStream out)
throws IOException{
out.writeByte(tag);
out.writeInt(bytes);
}
}
ClassFiles内のCONSTANT_InterfaceMethodref_info構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** InterfaceMethodref subtype of a constant pool entry.
*/
public final class CONSTANT_InterfaceMethodref_info extends cp_info{
/** The index to the class that this field is referencing to. */
public int class_index;
/** The name and type index this field if referencing to. */
public int name_and_type_index;
public CONSTANT_InterfaceMethodref_info(int class_index,
int name_and_type_index) {
tag = 11;
this.class_index = class_index;
this.name_and_type_index = name_and_type_index;
}
/** Used during input serialization by ClassFile only. */
CONSTANT_InterfaceMethodref_info(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
if (tag != 11)
throw new ClassFormatError();
class_index = in.readChar();
name_and_type_index = in.readChar();
}
/** Used during output serialization by ClassFile only. */
void serialize(DataOutputStream out)
throws IOException{
out.writeByte(tag);
out.writeChar(class_index);
out.writeChar(name_and_type_index);
}
}
ClassFiles内のCONSTANT_Long_info構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** Long subtype of a constant pool entry. */
public final class CONSTANT_Long_info extends cp_info{
/** The actual value. */
public long bytes;
public CONSTANT_Long_info(long b){
tag = 5;
bytes = b;
}
/** Used during input serialization by ClassFile only. */
CONSTANT_Long_info(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
if (tag != 5)
throw new ClassFormatError();
bytes = in.readLong();
}
/** Used during output serialization by ClassFile only. */
void serialize(DataOutputStream out)
throws IOException{
out.writeByte(tag);
out.writeLong(bytes);
}
}
ClassFiles内のCONSTANT_Methodref_info構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** Methodref subtype of a constant pool entry.
*/
public final class CONSTANT_Methodref_info extends cp_info{
/** The index to the class that this field is referencing to. */
public int class_index;
/** The name and type index this field if referencing to. */
public int name_and_type_index;
public CONSTANT_Methodref_info(int class_index, int name_and_type_index) {
tag = 10;
this.class_index = class_index;
this.name_and_type_index = name_and_type_index;
}
/** Used during input serialization by ClassFile only. */
CONSTANT_Methodref_info(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
if (tag != 10)
throw new ClassFormatError();
class_index = in.readChar();
name_and_type_index = in.readChar();
}
/** Used during output serialization by ClassFile only. */
void serialize(DataOutputStream out)
throws IOException{
out.writeByte(tag);
out.writeChar(class_index);
out.writeChar(name_and_type_index);
}
}
ClassFiles内のCONSTANT_NameAndType_info構造を表わすためのコンビエンスクラス
import java.io.*;
import java.lang.*;
/** NameAndType subtype of a constant pool entry.
*/
public final class CONSTANT_NameAndType_info extends cp_info{
/** The index to the Utf8 that contains the name. */
public int name_index;
/** The index fo the Utf8 that constains the signature. */
public int descriptor_index;
public CONSTANT_NameAndType_info(int name_index, int descriptor_index) {
tag = 12;
this.name_index = name_index;
this.descriptor_index = descriptor_index;
}
/** Used during input serialization by ClassFile only. */
CONSTANT_NameAndType_info(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
if (tag != 12)
throw new ClassFormatError();
name_index = in.readChar();
descriptor_index = in.readChar();
}
/** Used during output serialization by ClassFile only. */
void serialize(DataOutputStream out)
throws IOException{
out.writeByte(tag);
out.writeChar(name_index);
out.writeChar(descriptor_index);
}
}
ClassFiles内のCONSTANT_String_info構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** String subtype of a constant pool entry.
*/
public final class CONSTANT_String_info extends cp_info{
/** The index to the actual value of the string. */
public int string_index;
public CONSTANT_String_info(int value) {
tag = 8;
string_index = value;
}
/** ONLY TO BE USED BY CLASSFILE! */
public CONSTANT_String_info(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
if (tag != 8)
throw new ClassFormatError();
string_index = in.readChar();
}
/** Output serialization, ONLY TO BE USED BY CLASSFILE! */
public void serialize(DataOutputStream out)
throws IOException{
out.writeByte(tag);
out.writeChar(string_index);
}
}
ClassFiles内のCONSTANT_Utf8_info構造を表わすためのコンビエンスクラス
import java.io.*;
import java.lang.*;
/** Utf8 subtype of a constant pool entry.
* We internally represent the Utf8 info byte array
* as a String.
*/
public final class CONSTANT_Utf8_info extends cp_info{
/** Length of the byte array. */
public int length;
/** The actual bytes, represented by a String. */
public String bytes;
/** This constructor should be used for the purpose
* of part creation. It does not set the parent
* ClassFile reference.
*/
public CONSTANT_Utf8_info(String s) {
tag = 1;
length = s.length();
bytes = s;
}
/** Used during input serialization by ClassFile only. */
public CONSTANT_Utf8_info(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
if (tag != 1)
throw new ClassFormatError();
length = in.readChar();
byte[] b = new byte[length];
in.read(b, 0, length);
// WARNING: String constructor is deprecated.
bytes = new String(b, 0, length);
}
/** Used during output serialization by ClassFile only. */
public void serialize(DataOutputStream out)
throws IOException{
out.writeByte(tag);
out.writeChar(length);
// WARNING: Handling of String coversion here might be problematic.
out.writeBytes(bytes);
}
public String toString(){
return bytes;
}
}
ClassFiles内のConstantValue_attribute構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** Attribute that allows for initialization of static variables in
* classes. This attribute will only reside in a field_info struct.
*/
public final class ConstantValue_attribute extends attribute_info{
public int constantvalue_index;
public ConstantValue_attribute(ClassFile cf, int ani, int al, int cvi){
super(cf);
attribute_name_index = ani;
attribute_length = al;
constantvalue_index = cvi;
}
public ConstantValue_attribute(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
constantvalue_index = in.readChar();
}
public void serialize(DataOutputStream out)
throws IOException{
attribute_length = 2;
super.serialize(out);
out.writeChar(constantvalue_index);
}
}
ClassFiles内のcp_info構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** Represents the common interface of all constant pool parts
* that all specific constant pool items must inherit from.
*
*/
public abstract class cp_info{
/** The type tag that signifies what kind of constant pool
* item it is */
public int tag;
/** Used for serialization of the object back into a bytestream. */
abstract void serialize(DataOutputStream out) throws IOException;
/** Default constructor. Simply does nothing. */
public cp_info() {}
/** Constructor simply takes in the ClassFile as a reference to
* it's parent
*/
public cp_info(ClassFile cf) {}
/** Used during input serialization by ClassFile only. */
cp_info(ClassFile cf, DataInputStream in)
throws IOException{
tag = in.readUnsignedByte();
}
}
ClassFiles内のDeprecated_attrbiute構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** A fix attributed that can be located either in the ClassFile,
* field_info or the method_info attribute. Mark deprecated to
* indicate that the method, class or field has been superceded.
*/
public final class Deprecated_attribute extends attribute_info{
public Deprecated_attribute(ClassFile cf, int ani, int al){
super(cf);
attribute_name_index = ani;
attribute_length = al;
}
/** Used during input serialization by ClassFile only. */
Deprecated_attribute(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
}
}
ClassFiles内のExceptions_attribute構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** This is the struct where the exceptions table are located.
* <br><br>
* This attribute can only appear once in a method_info struct.
*/
public final class Exceptions_attribute extends attribute_info{
public int number_of_exceptions;
public int[] exception_index_table;
public Exceptions_attribute(ClassFile cf, int ani, int al, int noe,
int[] eit){
super(cf);
attribute_name_index = ani;
attribute_length = al;
number_of_exceptions = noe;
exception_index_table = eit;
}
/** Used during input serialization by ClassFile only. */
Exceptions_attribute(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
number_of_exceptions = in.readChar();
exception_index_table = new int[number_of_exceptions];
for (int i=0; i<number_of_exceptions; i++)
exception_index_table[i] = in.readChar();
}
/** Used during output serialization by ClassFile only. */
public void serialize(DataOutputStream out)
throws IOException{
attribute_length = 2 + (number_of_exceptions*2);
super.serialize(out);
out.writeChar(number_of_exceptions);
for (int i=0; i<number_of_exceptions; i++)
out.writeChar(exception_index_table[i]);
}
}
ClassFiles内のfield_info構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** Represents the field_info structure as specified in the JVM specification.
*/
public final class field_info{
public int access_flags;
public int name_index;
public int descriptor_index;
public int attributes_count;
public attribute_info[] attributes;
/** Convenience constructor. */
public field_info(ClassFile cf, int flags, int ni, int di){
access_flags = flags;
name_index = ni;
descriptor_index = di;
attributes_count = 0;
attributes = new attribute_info[0];
}
/** Constructor called only during the serialization process.
* <br><br>
* This is intentionally left as package protected as we
* should not normally call this constructor directly.
* <br><br>
* Warning: the handling of len is not correct (after String s =...)
*/
field_info(ClassFile cf, DataInputStream in)
throws IOException{
access_flags = in.readChar();
name_index = in.readChar();
descriptor_index = in.readChar();
attributes_count = in.readChar();
attributes = new attribute_info[attributes_count];
for (int i=0; i<attributes_count; i++){
in.mark(2);
String s = cf.constant_pool[in.readChar()].toString();
in.reset();
if (s.equals(“ConstantValue”))
attributes[i] = new ConstantValue_attribute(cf, in);
else if (s.equals(“Synthetic”))
attributes[i] = new Synthetic_attribute(cf, in);
else if (s.equals(“Deprecated”))
attributes[i] = new Deprecated_attribute(cf, in);
else
attributes[i] = new attribute_info.Unknown(cf, in);
}
}
/** To serialize the contents into the output format.
*/
public void serialize(DataOutputStream out)
throws IOException{
out.writeChar(access_flags);
out.writeChar(name_index);
out.writeChar(descriptor_index);
out.writeChar(attributes_count);
for (int i=0; i<attributes_count; i++)
attributes[i].serialize(out);
}
}
ClassFiles内のInnerClasses_attribute構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** A variable length structure that contains information about an
* inner class of this class.
*/
public final class InnerClasses_attribute extends attribute_info{
public int number_of_classes;
public classes[] classes;
public final static class classes{
int inner_class_info_index;
int outer_class_info_index;
int inner_name_index;
int inner_class_access_flags;
}
public InnerClasses_attribute(ClassFile cf, int ani, int al,
int noc, classes[] c){
super(cf);
attribute_name_index = ani;
attribute_length = al;
number_of_classes = noc;
classes = c;
}
/** Used during input serialization by ClassFile only. */
InnerClasses_attribute(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
number_of_classes = in.readChar();
classes = new InnerClasses_attribute.classes[number_of_classes];
for (int i=0; i<number_of_classes; i++){
classes[i] = new classes();
classes[i].inner_class_info_index = in.readChar();
classes[i].outer_class_info_index = in.readChar();
classes[i].inner_name_index = in.readChar();
classes[i].inner_class_access_flags = in.readChar();
}
}
/** Used during output serialization by ClassFile only. */
public void serialize(DataOutputStream out)
throws IOException{
attribute_length = 2 + (number_of_classes * 8);
super.serialize(out);
out.writeChar(number_of_classes);
for (int i=0; i<number_of_classes; i++){
out.writeChar(classes[i].inner_class_info_index);
out.writeChar(classes[i].outer_class_info_index);
out.writeChar(classes[i].inner_name_index);
out.writeChar(classes[i].inner_class_access_flags);
}
}
}
ClassFiles内のLineNumberTable_attribute構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** Determines which line of the binary code relates to the
* corresponding source code.
*/
public final class LineNumberTable_attribute extends attribute_info{
public int line_number_table_length;
public line_number_table[] line_number_table;
public final static class line_number_table{
int start_pc;
int line_number;
}
public LineNumberTable_attribute(ClassFile cf, int ani, int al, int lntl,
line_number_table[] lnt){
super(cf);
attribute_name_index = ani;
attribute_length = al;
line_number_table_length = lntl;
line_number_table = lnt;
}
/** Used during input serialization by ClassFile only. */
LineNumberTable_attribute(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
line_number_table_length = in.readChar();
line_number_table = new LineNumberTable_attribute.line_number_table[line_number_table_length];
for (int i=0; i<line_number_table_length; i++){
line_number_table[i] = new line_number_table();
line_number_table[i].start_pc = in.readChar();
line_number_table[i].line_number = in.readChar();
}
}
/** Used during output serialization by ClassFile only. */
void serialize(DataOutputStream out)
throws IOException{
attribute_length = 2 + (line_number_table_length * 4);
super.serialize(out);
out.writeChar(line_number_table_length);
for (int i=0; i<line_number_table_length; i++){
out.writeChar(line_number_table[i].start_pc);
out.writeChar(line_number_table[i].line_number);
}
}
}
ClassFiles内のLocalVariableTable_attribute構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** Used by debugger to find out how the source file line number is linked
* to the binary code. It has many to one correspondence and is found in
* the Code_attribute.
*/
public final class LocalVariableTable_attribute extends attribute_info{
public int local_variable_table_length;
public local_variable_table[] local_variable_table;
public final static class local_variable_table{
int start_pc;
int length;
int name_index;
int descriptor_index;
int index;
}
public LocalVariableTable_attribute(ClassFile cf, int ani, int al,
int lvtl, local_variable_table[] lvt){
super(cf);
attribute_name_index = ani;
attribute_length = al;
local_variable_table_length = lvtl;
local_variable_table = lvt;
}
/** Used during input serialization by ClassFile only. */
LocalVariableTable_attribute(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
local_variable_table_length = in.readChar();
local_variable_table = new LocalVariableTable_attribute.local_variable_table[local_variable_table_length];
for (int i=0; i<local_variable_table_length; i++){
local_variable_table[i] = new local_variable_table();
local_variable_table[i].start_pc = in.readChar();
local_variable_table[i].length = in.readChar();
local_variable_table[i].name_index = in.readChar();
local_variable_table[i].descriptor_index = in.readChar();
local_variable_table[i].index = in.readChar();
}
}
/** Used during output serialization by ClassFile only. */
void serialize(DataOutputStream out)
throws IOException{
attribute_length = 2 + (local_variable_table_length * 10);
super.serialize(out);
out.writeChar(local_variable_table_length);
for (int i=0; i<local_variable_table_length; i++){
out.writeChar(local_variable_table[i].start_pc);
out.writeChar(local_variable_table[i].length);
out.writeChar(local_variable_table[i].name_index);
out.writeChar(local_variable_table[i].descriptor_index);
out.writeChar(local_variable_table[i].index);
}
}
}
ClassFiles内のmethod_info構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** This follows the method_info in the JVM specification.
*/
public final class method_info {
public int access_flags;
public int name_index;
public int descriptor_index;
public int attributes_count;
public attribute_info[] attributes;
/** Constructor. Creates a method_info, initializes it with
* the flags set, and the name and descriptor indexes given.
* A new uninitialized code attribute is also created, and stored
* in the <i>code</i> variable.*/
public method_info(ClassFile cf, int flags, int ni, int di,
int ac, attribute_info[] a) {
access_flags = flags;
name_index = ni;
descriptor_index = di;
attributes_count = ac;
attributes = a;
}
/** This method creates a method_info from the current pointer in the
* data stream. Only called by during the serialization of a complete
* ClassFile from a bytestream, not normally invoked directly.
*/
method_info(ClassFile cf, DataInputStream in)
throws IOException{
access_flags = in.readChar();
name_index = in.readChar();
descriptor_index = in.readChar();
attributes_count = in.readChar();
attributes = new attribute_info[attributes_count];
for (int i=0; i<attributes_count; i++){
in.mark(2);
String s = cf.constant_pool[in.readChar()].toString();
in.reset();
if (s.equals(“Code”))
attributes[i] = new Code_attribute(cf, in);
else if (s.equals(“Exceptions”))
attributes[i] = new Exceptions_attribute(cf, in);
else if (s.equals(“Synthetic”))
attributes[i] = new Synthetic_attribute(cf, in);
else if (s.equals(“Deprecated”))
attributes[i] = new Deprecated_attribute(cf, in);
else
attributes[i] = new attribute_info.Unknown(cf, in);
}
}
/** Output serialization of the method_info to a byte array.
* Not normally invoked directly.
*/
public void serialize(DataOutputStream out)
throws IOException{
out.writeChar(access_flags);
out.writeChar(name_index);
out.writeChar(descriptor_index);
out.writeChar(attributes_count);
for (int i=0; i<attributes_count; i++)
attributes[i].serialize(out);
}
}
ClassFiles内のSourceFile_attribute構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** A SourceFile attribute is an optional fixed_length attribute in
* the attributes table. Only located in the ClassFile struct only
* once.
*/
public final class SourceFile_attribute extends attribute_info{
public int sourcefile_index;
public SourceFile_attribute(ClassFile cf, int ani, int al, int sfi){
super(cf);
attribute_name_index = ani;
attribute_length = al;
sourcefile_index = sfi;
}
/** Used during input serialization by ClassFile only. */
SourceFile_attribute(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
sourcefile_index = in.readChar();
}
/** Used during output serialization by ClassFile only. */
void serialize(DataOutputStream out)
throws IOException{
attribute_length = 2;
super.serialize(out);
out.writeChar(sourcefile_index);
}
}
ClassFiles内のSynthetic_attribute構造を表わすためのコンビエンスクラス
import java.lang.*;
import java.io.*;
/** A synthetic attribute indicates that this class does not have
* a generated code source. It is likely to imply that the code
* is generated by machine means rather than coded directly. This
* attribute can appear in the classfile, method_info or field_info.
* It is fixed length.
*/
public final class Synthetic_attribute extends attribute_info{
public Synthetic_attribute(ClassFile cf, int ani, int al){
super(cf);
attribute_name_index = ani;
attribute_length = al;
}
/** Used during output serialization by ClassFile only. */
Synthetic_attribute(ClassFile cf, DataInputStream in)
throws IOException{
super(cf, in);
}
}
Method void run()
0 getstatic #2 <Field java.lang.Object LOCK>
3 dup
4 astore_1
5 monitorenter
6 getstatic #3 <Field int counter>
9 iconst_1
10 iadd
11 putstatic #3 <Field int counter>
14 aload_1
15 monitorexit
16 return
Method void run()
0 getstatic #2 <Field java.lang.Object LOCK>
3 dup
4 astore_1
5 dup
6 monitorenter
7 invokestatic #23 <Method void acquireLock(java.lang.Object)>
10 getstatic #3 <Field int counter>
13 iconst_1
14 iadd
15 putstatic #3 <Field int counter>
18 aload_1
19 dup
20 invokestatic #24 <Method void releaseLock(java.lang.Object)>
23 monitorexit
24 return
import java.lang.*;
public class example{
/** Shared static field. */
public final static Object LOCK = new Object();
/** Shared static field. */
public static int counter = 0;
/** Example method using synchronization. This method serves to
illustrate the use of synchronization to implement thread-safe
modification of a shared memory location by potentially multiple
threads. */
public void run(){
// First acquire the lock, otherwise any memory writes we do will be
// prone to race-conditions.
synchronized (LOCK){
// Now that we have acquired the lock, we can safely modify memory
// in a thread-safe manner.
counter++;
}
}
}
import java.lang.*;
import java.util.*;
import java.net.*;
import java.io.*;
public class LockClient{
/** Protocol specific values. */
public final static int CLOSE = -1;
public final static int NACK = 0;
public final static int ACK = 1;
public final static int ACQUIRE_LOCK = 10;
public final static int RELEASE_LOCK = 20;
/** LockServer network values. */
public final static String serverAddress =
System.getProperty(“LockServer_network_address”);
public final static int serverPort =
Integer.parseInt(System.getProperty(“LockServer_network_port”));
/** Table of global ID's for local objects. (hashcode-to-globalID
mappings) */
public final static Hashtable hashCodeToGlobalID = new Hashtable();
/** Called when an application is to acquire a lock. */
public static void acquireLock(Object o){
// First of all, we need to resolve the globalID for object 'o'.
// To do this we use the hashCodeToGlobalID table.
int globalID = ((Integer) hashCodeToGlobalID.get(o)).intValue();
try{
// Next, we want to connect to the LockServer, which will grant us
// the global lock.
Socket socket = new Socket(serverAddress, serverPort);
DataOutputStream out =
new DataOutputStream(socket.getOutputStream());
DataInputStream in = new DataInputStream(socket.getInputStream());
// Ok, now send the serialized request to the lock server.
out.writeInt(ACQUIRE_LOCK);
out.writeInt(globalID);
out.flush();
// Now wait for the reply.
int status = in.readInt();// This is a blocking call. So we
// will wait until the remote side
// sends something.
if (status == NACK){
throw new AssertionError(
“Negative acknowledgement. Request failed.”);
}else if (status != ACK){
throw new AssertionError(“Unknown acknowledgement: ”
+ status + “. Request failed.”);
}
// Close down the connection.
out.writeInt(CLOSE);
out.flush();
out.close();
in.close();
socket.close();// Make sure to close the socket.
// This is a good acknowledgement, thus we can return now because
// global lock is now acquired.
return;
}catch (IOException e){
throw new AssertionError(“Exception: ” + e.toString());
}
}
/** Called when an application is to release a lock. */
public static void releaseLock(Object o){
// First of all, we need to resolve the globalID for object 'o'.
// To do this we use the hashCodeToGlobalID table.
int globalID = ((Integer) hashCodeToGlobalID.get(o)).intValue();
try{
// Next, we want to connect to the LockServer, which records us as
// the owner of the global lock for object 'o'.
Socket socket = new Socket(serverAddress, serverPort);
DataOutputStream out =
new DataOutputStream(socket.getOutputStream());
DataInputStream in = new DataInputStream(socket.getInputStream());
// Ok, now send the serialized request to the lock server.
out.writeInt(RELEASE_LOCK);
out.writeInt(globalID);
out.flush();
// Now wait for the reply.
int status = in.readInt();// This is a blocking call. So we
// will wait until the remote side
// sends something.
if (status == NACK){
throw new AssertionError(
“Negative acknowledgement. Request failed.”);
}else if (status != ACK){
throw new AssertionError(“Unknown acknowledgement: ”
+ status + “. Request failed.”);
}
// Close down the connection.
out.writeInt(CLOSE);
out.flush();
out.close();
in.close();
socket.close(); // Make sure to close the socket.
// This is a good acknowledgement, return because global lock is
// now released.
return;
}catch (IOException e){
throw new AssertionError(“Exception: ” + e.toString());
}
}
}
import java.lang.*;
import java.util.*;
import java.net.*;
import java.io.*;
public class LockServer implements Runnable{
/** Protocol specific values */
public final static int CLOSE = -1;
public final static int NACK = 0;
public final static int ACK = 1;
public final static int ACQUIRE_LOCK = 10;
public final static int RELEASE_LOCK = 20;
/** LockServer network values. */
public final static int serverPort = 20001;
/** Table of lock records. */
public final static Hashtable locks = new Hashtable();
/** Linked list of waiting LockManager objects. */
public LockServer next = null;
/** Address of remote LockClient. */
public final String address;
/** Private input/output objects. */
private Socket socket = null;
private DataOutputStream outputStream;
private DataInputStream inputStream;
public static void main(String[] s)
throws Exception{
System.out.println(“LockServer_network_address=”
+ InetAddress.getLocalHost().getHostAddress());
System.out.println(“LockServer_network_port=” + serverPort);
// Create a serversocket to accept incoming lock operation
// connections.
ServerSocket serverSocket = new ServerSocket(serverPort);
while (!Thread.interrupted()){
// Block until an incoming lock operation connection.
Socket socket = serverSocket.accept();
// Create a new instance of LockServer to manage this lock
// operation connection.
new Thread(new LockServer(socket)).start();
}
}
/** Constructor. Initialise this new LockServer instance with necessary
resources for operation. */
public LockServer(Socket s){
socket = s;
try{
outputStream = new DataOutputStream(s.getOutputStream());
inputStream = new DataInputStream(s.getInputStream());
address = s.getInetAddress().getHostAddress();
}catch (IOException e){
throw new AssertionError(“Exception: ” + e.toString());
}
}
/** Main code body. Decode incoming lock operation requests and execute
accordingly. */
public void run(){
try{
// All commands are implemented as 32bit integers.
// Legal commands are listed in the “protocol specific values”
// fields above.
int command = inputStream.readInt();
// Continue processing commands until a CLOSE operation.
while (command != CLOSE){
if (command == ACQUIRE_LOCK){ // This is an
// ACQUIRE_LOCK
// operation.
// Read in the globalID of the object to be locked.
int globalID = inputStream.readInt();
// Synchronize on the locks table in order to ensure thread-
// safety.
synchronized (locks){
// Check for an existing owner of this lock.
LockServer lock = (LockServer) locks.get(
new Integer(globalID));
if (lock == null){// No-one presently owns this lock,
// so acquire it.
locks.put(new Integer(globalID), this);
acquireLock(); // Signal to the client the
// successful acquisition of this
// lock.
}else{ // Already owned. Append ourselves
// to end of queue.
// Search for the end of the queue. (Implemented as
// linked-list)
while (lock.next != null){
lock = lock.next;
}
lock.next = this;// Append this lock request at end.
}
}
}else if (command == RELEASE_LOCK){// This is a
// RELEASE_LOCK
// operation.
// Read in the globalID of the object to be locked.
int globalID = inputStream.readInt();
// Synchronize on the locks table in order to ensure thread-
// safety.
synchronized (locks){
// Check to make sure we are the owner of this lock.
LockServer lock = (LockServer) locks.get(
new Integer(globalID));
if (lock == null){
throw new AssertionError(“Unlocked. Release failed.”);
}else if (lock.address != this.address){
throw new AssertionError(“Trying to release a lock ”
+ “which this client doesn't own. Release ”
+ “failed.”);
}
lock = lock.next;
lock.acquireLock();// Signal to the client the
// successful acquisition of this
// lock.
// Shift the linked list of pending acquisitions forward
// by one.
locks.put(new Integer(globalID), lock);
// Clear stale reference.
next = null;
}
releaseLock(); // Signal to the client the successful
// release of this lock.
}else{ // Unknown command.
throw new AssertionError(
“Unknown command. Operation failed.”);
}
// Read in the next command.
command = inputStream.readInt();
}
}catch (Exception e){
throw new AssertionError(“Exception: ” + e.toString());
}finally{
try{
// Closing down. Cleanup this connection.
outputStream.flush();
outputStream.close();
inputStream.close();
socket.close();
}catch (Throwable t){
t.printStackTrace();
}
// Garbage these references.
outputStream = null;
inputStream = null;
socket = null;
}
}
/** Send a positive acknowledgement of an ACQUIRE_LOCK operation. */
public void acquireLock() throws IOException{
outputStream.writeInt(ACK);
outputStream.flush();
}
/** Send a positive acknowledgement of a RELEASE_LOCK operation. */
public void releaseLock() throws IOException{
outputStream.writeInt(ACK);
outputStream.flush();
}
}
Lock Loader.java
この引用は、ロード時にアプリケーションを修正するLock Loaderのソースコードである。
import java.lang.*;
import java.io.*;
import java.net.*;
public class LockLoader extends URLClassLoader{
public LockLoader(URL[] urls){
super(urls);
}
protected Class findClass(String name)
throws ClassNotFoundException{
ClassFile cf = null;
try{
BufferedInputStream in =
new BufferedInputStream(findResource(name.replace('.',
'/').concat(“.class”)).openStream());
cf = new ClassFile(in);
}catch (Exception e){throw new ClassNotFoundException(e.toString());}
// Class-wide pointers to the enterindex and exitindex.
int enterindex = -1;
int exitindex = -1;
for (int i=0; i<cf.methods_count; i++){
for (int j=0; j<cf.methods[i].attributes_count; j++){
if (!(cf.methods[i].attributes[j] instanceof Code_attribute))
continue;
Code_attribute ca = (Code_attribute) cf.methods[i].attributes[j];
boolean changed = false;
for (int z=0; z<ca.code.length; z++){
if ((ca.code[z][0] & 0xff) == 194){ // Opcode for a
// MONITORENTER
// instruction.
changed = true;
// Next, realign the code array, making room for the
// insertions.
byte[][] code2 = new byte[ca.code.length+2][];
System.arraycopy(ca.code, 0, code2, 0, z);
code2[z+1] = ca.code[z];
System.arraycopy(ca.code, z+1, code2, z+3,
ca.code.length-(z+1));
ca.code = code2;
// Next, insert the DUP instruction.
ca.code[z] = new byte[1];
ca.code[z][0] = (byte) 89;
// Finally, insert the INVOKESTATIC instruction.
if (enterindex == -1){
// This is the first time this class is encourtering the
// acquirelock instruction, so have to add it to the
// constant pool.
cp_info[] cpi = new cp_info[cf.constant_pool.length+6];
System.arraycopy(cf.constant_pool, 0, cpi, 0,
cf.constant_pool.length);
cf.constant_pool = cpi;
cf.constant_pool_count += 6;
CONSTANT_Utf8_info u1 =
new CONSTANT_Utf8_info(“LockClient”);
cf.constant_pool[cf.constant_pool.length-6] = u1;
CONSTANT_Class_info c1 = new CONSTANT_Class_info(
cf.constant_pool_count-6);
cf.constant_pool[cf.constant_pool.length-5] = c1;
u1 = new CONSTANT_Utf8_info(“acquireLock”);
cf.constant_pool[cf.constant_pool.length-4] = u1;
u1 = new CONSTANT_Utf8_info(“(Ljava/lang/Object;)V”);
cf.constant_pool[cf.constant_pool.length-3] = u1;
CONSTANT_NameAndType_info n1 =
new CONSTANT_NameAndType_info(
cf.constant_pool.length-4, cf.constant_pool.length-3);
cf.constant_pool[cf.constant_pool.length-2] = n1;
CONSTANT_Methodref_info m1 = new CONSTANT_Methodref_info(
cf.constant_pool.length-5, cf.constant_pool.length-2);
cf.constant_pool[cf.constant_pool.length-1] = m1;
enterindex = cf.constant_pool.length-1;
}
ca.code[z+2] = new byte[3];
ca.code[z+2][0] = (byte) 184;
ca.code[z+2][1] = (byte) ((enterindex >> 8) & 0xff);
ca.code[z+2][2] = (byte) (enterindex & 0xff);
// And lastly, increase the CODE_LENGTH and ATTRIBUTE_LENGTH
// values.
ca.code_length += 4;
ca.attribute_length += 4;
z += 1;
}else if ((ca.code[z][0] & 0xff) == 195){// Opcode for a
// MONITOREXIT
// instruction.
changed = true;
// Next, realign the code array, making room for the
// insertions.
byte[][] code2 = new byte[ca.code.length+2][];
System.arraycopy(ca.code, 0, code2, 0, z);
code2[z+1] = ca.code[z];
System.arraycopy(ca.code, z+1, code2, z+3,
ca.code.length-(z+1));
ca.code = code2;
// Next, insert the DUP instruction.
ca.code[z] = new byte[1];
ca.code[z][0] = (byte) 89;
// Finally, insert the INVOKESTATIC instruction.
if (exitindex == -1){
// This is the first time this class is encourtering the
// acquirelock instruction, so have to add it to the
// constant pool.
cp_info[] cpi = new cp_info[cf.constant_pool.length+6];
System.arraycopy(cf.constant_pool, 0, cpi, 0,
cf.constant_pool.length);
cf.constant_pool = cpi;
cf.constant_pool_count += 6;
CONSTANT_Utf8_info u1 =
new CONSTANT_Utf8_info(“LockClient”);
cf.constant_pool[cf.constant_pool.length-6] = u1;
CONSTANT_Class_info c1 = new CONSTANT_Class_info(
cf.constant_pool_count-6);
cf.constant_pool[cf.constant_pool.length-5] = c1;
u1 = new CONSTANT_Utf8_info(“releaseLock”);
cf.constant_pool[cf.constant_pool.length-4] = u1;
u1 = new CONSTANT_Utf8_info(“(Ljava/lang/Object;)V”);
cf.constant_pool[cf.constant_pool.length-3] = u1;
CONSTANT_NameAndType_info n1 =
new CONSTANT_NameAndType_info(
cf.constant_pool.length-4, cf.constant_pool.length-3);
cf.constant_pool[cf.constant_pool.length-2] = n1;
CONSTANT_Methodref_info m1 = new CONSTANT_Methodref_info(
cf.constant_pool.length-5, cf.constant_pool.length-2);
cf.constant_pool[cf.constant_pool.length-1] = m1;
exitindex = cf.constant_pool.length-1;
}
ca.code[z+2] = new byte[3];
ca.code[z+2][0] = (byte) 184;
ca.code[z+2][1] = (byte) ((exitindex >> 8) & 0xff);
ca.code[z+2][2] = (byte) (exitindex & 0xff);
// And lastly, increase the CODE_LENGTH and ATTRIBUTE_LENGTH
// values.
ca.code_length += 4;
ca.attribute_length += 4;
z += 1;
}
}
// If we changed this method, then increase the stack size by one.
if (changed){
ca.max_stack++; // Just to make sure.
}
}
}
try{
ByteArrayOutputStream out = new ByteArrayOutputStream();
cf.serialize(out);
byte[] b = out.toByteArray();
return defineClass(name, b, 0, b.length);
}catch (Exception e){
throw new ClassNotFoundException(name);
}
}
}
53 ネットワーク
71 DRT
Claims (30)
- 単一のコンピュータでのみ動作するように各々記述されているが、通信ネットワークによって相互接続された複数のコンピュータ上で同時に実行される少なくとも1つのアプリケーションプログラムを有する多重コンピュータシステムであって、
前記アプリケーションプログラムの異なる部分が前記コンピュータのうちの異なるコンピュータ上でほぼ同時に実行され、前記各部分において、実質的に同一な複数のオブジェクトが前記対応するコンピュータに各々作成され、各々が実質的に同一の名前を有し、前記システムは、前記コンピュータの全てに利用可能なロック手段を含み、コンピュータ内の名前を付けられたオブジェクトを利用したいと望んでいるあらゆるコンピュータが、前記ロック手段から許可ロックを取得し、前記許可ロックにより前記利用が許可され、前記許可ロックが放棄されるまで前記他のコンピュータ全てがこれらの対応する名前を付けられたオブジェクトを利用するのが阻止されることを特徴とする多重コンピュータシステム。 - 前記ロック手段は、ロック取得ルーチンとロック解放ルーチンとを含み、前記ルーチンの両方は、前記全てのコンピュータ上で実行される前記アプリケーションプログラムになされた修正に含まれることを特徴とする請求項1に記載のシステム。
- 前記ロック手段は、いずれかの前記コンピュータによって使用される前記名前を付けられたオブジェクト、前記各オブジェクトのロック状態、及びいずれかの未決のロック取得の待ち行列をリストする共有テーブルを更に含むことを特徴とする請求項2に記載のシステム。
- 前記ロック手段は、前記アプリケーションプログラムを実行しておらず、前記通信ネットワークに接続されている追加のコンピュータ内に位置付けられることを特徴とする請求項3に記載のシステム。
- 前記各アプリケーションプログラムは、前記ロック取得ルーチン及び前記ロック解放ルーチンを挿入して、前記アプリケーションプログラムがオブジェクトに対するロックをそれぞれ取得及び解放する各インスタンスを修正することによって、ロード前、ロード中、又はロード後に修正されることを特徴とする請求項2に記載のシステム。
- 前記アプリケーションプログラムは、ロード時の再コンパイル、ロード前の事前コンパイル、ロード前のコンパイル、実行時コンパイル、及びロード後で且つアプリケーションプログラムの前記関連部分の実行前の再コンパイルからなる手順のグループから選択される手順に従って修正されることを特徴とする請求項3に記載のシステム。
- 前記修正アプリケーションプログラムは、マスタ/スレーブ転送、ブランチ転送、及びカスケード転送からなるグループから選択される手順に従って前記コンピュータの全てに転送されることを特徴とする請求項2に記載のシステム。
- 通信リンクを介して相互接続され、単一のコンピュータでのみ動作するように各々記述されている少なくとも1つのアプリケーションプログラムを同時に実行する複数のコンピュータであって、
前記各コンピュータが前記アプリケーションプログラムの異なる部分をほぼ同時に実行し、前記アプリケーションプログラム部分を動作中の前記各コンピュータは、前記各コンピュータに物理的に位置付けられたローカルメモリ内にあるオブジェクトだけを利用し、前記各コンピュータによって利用される前記ローカルメモリのコンテンツは、基本的に類似しているが、各瞬間では同一でなく、前記コンピュータの全てのコンピュータが、1つのコンピュータだけによる前記ローカルオブジェクトの利用を許可するロック取得ルーチン及びロック解放ルーチンを有し、前記複数のコンピュータの残りの各々は、これらの対応するオブジェクトの利用からロックアウトされることを特徴とする複数のコンピュータ。 - 前記又は前記各アプリケーションプログラムに割り当てられたローカルメモリ容量が実質的に同一であり、前記又は前記各アプリケーションプログラムが利用可能な総メモリ容量が、前記割り当てられたメモリ容量であることを特徴とする請求項8に記載の複数のコンピュータ。
- 前記分散更新手段の全ては、前記ローカルメモリ読み取り速度よりも遅いデータ転送速度で前記通信リンクを介して伝達することを特徴とする請求項8に記載の複数のコンピュータ。
- 前記コンピュータの少なくとも幾つかは、種々の製造業者によって製造され、及び/又は種々のオペレーティングシステムを有することを特徴とする請求項8に記載の複数のコンピュータ。
- 単一のコンピュータでのみ動作するように各々記述されている少なくとも1つのアプリケーションプログラムを複数のコンピュータ上で同時に実行する方法であって、前記コンピュータは、通信ネットワークによって相互接続されており、前記方法が、
(i)前記コンピュータのうちの異なるコンピュータ上で前記アプリケーションプログラムの異なる部分を実行し、前記各部分について前記対応するコンピュータ内に実質的に同一な複数のオブジェクトを各々作成し、各々に実質的に同一の名前を持たせる段階と、
(ii)コンピュータ内の名前を付けられたオブジェクトを利用することを意図する前記コンピュータのいずれにも、前記利用を許可し、前記許可ロックが放棄されるまで前記他のコンピュータの全てがこれらの対応する名前を付けられたオブジェクトの利用を阻止する許可ロックを取得するように要求する段階と、
を含む方法。 - (iii)前記通信ネットワークを介して前記コンピュータ間で伝達するための分散ランタイム手段を前記各コンピュータに提供する段階を更に含む請求項12に記載の方法。
- (iv)前記各分散ランタイム手段によってアクセス可能であり、オブジェクトに現在アクセスする必要のあるあらゆるコンピュータのアイデンティティを前記オブジェクトのアイデンティティと共に記憶される共有テーブルを提供する段階を更に含む請求項13に記載の方法。
- 前記オブジェクトへのアクセスを求める前記コンピュータの数のカウントを記憶するカウンタ手段を前記共有テーブルに関連付ける段階(v)を更に含む請求項14に記載の方法。
- 前記共有プログラムが実行されておらず、前記共有テーブル及びカウンタをホストする追加のコンピュータを提供する段階であって、該追加のコンピュータが前記通信ネットワークに接続されている提供段階(vi)を更に含む求項15に記載の方法。
- 単一のコンピュータでのみ動作するように記述されているが、通信ネットワークを介して相互接続された複数のコンピュータの異なるコンピュータ上でその異なる部分が各々ほぼ同時に実行されることになるアプリケーションプログラムの矛盾のない同期を保証する方法であって、前記方法が、
(i)ロード時、又はロード前、又はロード後に前記アプリケーションプログラムを精査して、同期ルーチンを定義する各プログラム段階を検出する段階と、
(ii)前記同期ルーチンを修正して1つだけのコンピュータによるオブジェクトの利用を保証し、前記残りのコンピュータ全てがこれらの対応するオブジェクトを同時に利用することを阻止する段階と、
を含む方法。 - 前記段階(ii)が、
(iii)前記コンピュータの1つで前記同期ルーチンをロードし実行する段階と、
(iv)前記1つのコンピュータによって前記同期ルーチンを修正する段階と、
(v)前記修正された同期ルーチンを前記残りのコンピュータの各々に転送する段階と、
を含む請求項17に記載の方法。 - 前記修正された同期ルーチンは、前記1つのコンピュータによって前記残りのコンピュータの各々に直接提供されることを特徴とする請求項18に記載の方法。
- 前記修正された同期ルーチンは、前記1つのコンピュータから前記残りのコンピュータの各々に順次にカスケード方式で提供されることを特徴とする請求項18に記載の方法。
- 前記段階(ii)が、
(vi)前記コンピュータの1つに前記同期ルーチンをロードし修正する段階と、
(vii)前記1つのコンピュータが前記残りのコンピュータの各々に前記未修正の同期ルーチンを送信する段階と、
(viii)前記残りのコンピュータの各々が前記同期ルーチンを受信した後に前記同期ルーチンを修正する段階と、
を含む請求項17に記載の方法。 - 前記未修正の同期ルーチンは、前記1つのコンピュータによって前記残りのコンピュータの各々に直接提供されることを特徴とする請求項21に記載の方法。
- 前記未修正の同期ルーチンは、前記1つのコンピュータから前記残りのコンピュータの各々に順次にカスケード方式で提供されることを特徴とする請求項21に記載の方法。
- (ix)ロード時の再コンパイル、ロード前の事前コンパイル、ロード前のコンパイル、実行時コンパイル、及びロード後で且つアプリケーションプログラムの関連部分の実行前の再コンパイルからなる手順のグループから選択される手順を利用して前記アプリケーションプログラムを修正する段階を更に含む請求項17に記載の方法。
- (x)マスタ/スレーブ転送、ブランチ転送、及びカスケード転送からなるグループから選択される手順を利用して前記コンピュータの全てに前記修正アプリケーションプログラムを転送する段階を更に含む請求項17に記載の方法。
- 単一のコンピュータ上でのみ動作するように記述された単一のアプリケーションプログラムの個々のスレッドが、通信リンクを介して相互接続された複数のコンピュータのうちの対応するコンピュータ上で各々同時に処理されるマルチスレッド処理コンピュータオペレーションにおいて、
各スレッドを処理する前記コンピュータに物理的に関連付けられたローカルメモリ内のオブジェクトは、他の前記各コンピュータのローカルメモリ内に対応するオブジェクトを有し、前記コンピュータの1つだけがオブジェクトを利用することを許可する段階と、前記残りのコンピュータの全てがこれらの対応するオブジェクトを同時に利用するのを阻止する段階とを含む改良方法。 - 1つの前記スレッドに関連付けられたメモリに常駐し且つ利用されることになるオブジェクトは、前記1つのスレッドのコンピュータによって他の前記コンピュータ全てがアクセス可能な共有テーブルに伝達されるアイデンティティを有することを特徴とする請求項26に記載の改良方法。
- 1つの前記スレッドに関連付けられたメモリに常駐し且つ利用されることになるオブジェクトは、別の前記スレッドに関連付けられた前記コンピュータに送信されるアイデンティティを有し、これによって前記他のコンピュータ全てがアクセス可能な共有テーブルに転送されることを特徴とする請求項26に記載の改良方法。
- 記憶媒体内に記憶され、請求項12又は17に記載される方法の実行を複数のコンピュータに許可するように動作可能なプログラム命令のセットを含むコンピュータプログラム製品。
- 通信ネットワークを介して相互接続された複数のコンピュータにおいて、単一のコンピュータでのみ動作するように各々記述されているが前記コンピュータ上で同時に実行されるアプリケーションプログラムの矛盾のない初期化を保証するよう動作可能な複数のコンピュータであって、前記コンピュータは、請求項12又は17に記載の方法を実行するようプログラムされており、或いは請求項29に記載のコンピュータプログラム製品がロードされていることを特徴とする複数のコンピュータ。
Applications Claiming Priority (2)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
AU2004902146A AU2004902146A0 (en) | 2004-04-22 | Modified Computer Architecture | |
PCT/AU2005/000579 WO2005103925A1 (en) | 2004-04-22 | 2005-04-22 | Multiple computer architecture with synchronization |
Publications (1)
Publication Number | Publication Date |
---|---|
JP2007534064A true JP2007534064A (ja) | 2007-11-22 |
Family
ID=35197170
Family Applications (4)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
JP2007508674A Pending JP2007534063A (ja) | 2004-04-22 | 2005-04-22 | オブジェクトの初期化を伴う改良型コンピュータアーキテクチャ |
JP2007508675A Pending JP2007534064A (ja) | 2004-04-22 | 2005-04-22 | 同期化を伴う多重コンピュータアーキテクチャ |
JP2007508677A Pending JP2007534066A (ja) | 2004-04-22 | 2005-04-22 | 複製メモリフィールドを備えたマルチコンピュータアーキテクチャ |
JP2007508676A Pending JP2007534065A (ja) | 2004-04-22 | 2005-04-22 | オブジェクトファイナライズによる改良型コンピュータアーキテクチャ |
Family Applications Before (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
JP2007508674A Pending JP2007534063A (ja) | 2004-04-22 | 2005-04-22 | オブジェクトの初期化を伴う改良型コンピュータアーキテクチャ |
Family Applications After (2)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
JP2007508677A Pending JP2007534066A (ja) | 2004-04-22 | 2005-04-22 | 複製メモリフィールドを備えたマルチコンピュータアーキテクチャ |
JP2007508676A Pending JP2007534065A (ja) | 2004-04-22 | 2005-04-22 | オブジェクトファイナライズによる改良型コンピュータアーキテクチャ |
Country Status (12)
Country | Link |
---|---|
EP (5) | EP1763774B1 (ja) |
JP (4) | JP2007534063A (ja) |
KR (1) | KR101209023B1 (ja) |
CN (2) | CN101908001B (ja) |
BR (1) | BRPI0508929A (ja) |
CA (1) | CA2563900C (ja) |
EA (1) | EA009926B1 (ja) |
IL (1) | IL178527A (ja) |
MX (1) | MXPA06012209A (ja) |
NZ (1) | NZ550480A (ja) |
WO (5) | WO2005103927A1 (ja) |
ZA (1) | ZA200608766B (ja) |
Families Citing this family (46)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US7844665B2 (en) | 2004-04-23 | 2010-11-30 | Waratek Pty Ltd. | Modified computer architecture having coordinated deletion of corresponding replicated memory locations among plural computers |
US7707179B2 (en) | 2004-04-23 | 2010-04-27 | Waratek Pty Limited | Multiple computer architecture with synchronization |
US7849452B2 (en) | 2004-04-23 | 2010-12-07 | Waratek Pty Ltd. | Modification of computer applications at load time for distributed execution |
WO2006110937A1 (en) | 2005-04-21 | 2006-10-26 | Waratek Pty Limited | Modified computer architecture with coordinated objects |
CN101283344B (zh) | 2005-10-10 | 2010-10-06 | 瓦拉泰克有限公司 | 具有增强的存储器清除的多计算机系统 |
WO2007041760A1 (en) * | 2005-10-10 | 2007-04-19 | Waratek Pty Limited | Modified machine architecture with advanced synchronization |
AU2006301908B2 (en) * | 2005-10-10 | 2011-09-15 | Waratek Pty Limited | Modified machine architecture with machine redundancy |
CN101283343B (zh) * | 2005-10-10 | 2010-05-19 | 瓦拉泰克有限公司 | 具有部分存储器更新的改进的机器体系结构 |
WO2007041764A1 (en) * | 2005-10-10 | 2007-04-19 | Waratek Pty Limited | Failure resistant multiple computer system and method |
AU2006301911B2 (en) * | 2005-10-10 | 2010-12-23 | Waratek Pty Limited | Failure resistant multiple computer system and method |
EP1934776A4 (en) * | 2005-10-10 | 2009-05-06 | Waratek Pty Ltd | REPLICATION OF GRAPHICS OF OBJECTS |
WO2007041761A1 (en) * | 2005-10-10 | 2007-04-19 | Waratek Pty Limited | Modified machine architecture with machine redundancy |
CN101288062B (zh) * | 2005-10-17 | 2012-03-21 | 瓦拉泰克有限公司 | 开销减少的多机器体系结构 |
US7958322B2 (en) | 2005-10-25 | 2011-06-07 | Waratek Pty Ltd | Multiple machine architecture with overhead reduction |
US7849369B2 (en) | 2005-10-25 | 2010-12-07 | Waratek Pty Ltd. | Failure resistant multiple computer system and method |
US8015236B2 (en) | 2005-10-25 | 2011-09-06 | Waratek Pty. Ltd. | Replication of objects having non-primitive fields, especially addresses |
US7581069B2 (en) | 2005-10-25 | 2009-08-25 | Waratek Pty Ltd. | Multiple computer system with enhanced memory clean up |
US7761670B2 (en) | 2005-10-25 | 2010-07-20 | Waratek Pty Limited | Modified machine architecture with advanced synchronization |
US7660960B2 (en) | 2005-10-25 | 2010-02-09 | Waratek Pty, Ltd. | Modified machine architecture with partial memory updating |
AU2007304895A1 (en) * | 2006-10-05 | 2008-04-10 | Waratek Pty Limited | Advanced contention detection |
US20080133884A1 (en) * | 2006-10-05 | 2008-06-05 | Holt John M | Multiple network connections for multiple computers |
US20080140863A1 (en) * | 2006-10-05 | 2008-06-12 | Holt John M | Multiple communication networks for multiple computers |
US20080140858A1 (en) | 2006-10-05 | 2008-06-12 | Holt John M | Switch protocol for network communications |
US20080141092A1 (en) * | 2006-10-05 | 2008-06-12 | Holt John M | Network protocol for network communications |
WO2008040074A1 (en) * | 2006-10-05 | 2008-04-10 | Waratek Pty Limited | Contention detection with data consolidation |
US20080140970A1 (en) * | 2006-10-05 | 2008-06-12 | Holt John M | Advanced synchronization and contention resolution |
US20080133869A1 (en) * | 2006-10-05 | 2008-06-05 | Holt John M | Redundant multiple computer architecture |
US20080140801A1 (en) * | 2006-10-05 | 2008-06-12 | Holt John M | Multiple computer system with dual mode redundancy architecture |
WO2008040065A1 (en) * | 2006-10-05 | 2008-04-10 | Waratek Pty Limited | Contention detection and resolution |
US8090926B2 (en) | 2006-10-05 | 2012-01-03 | Waratek Pty Ltd. | Hybrid replicated shared memory |
US20080133692A1 (en) * | 2006-10-05 | 2008-06-05 | Holt John M | Multiple computer system with redundancy architecture |
US20080126572A1 (en) * | 2006-10-05 | 2008-05-29 | Holt John M | Multi-path switching networks |
US20080126322A1 (en) * | 2006-10-05 | 2008-05-29 | Holt John M | Synchronization with partial memory replication |
US20080127213A1 (en) * | 2006-10-05 | 2008-05-29 | Holt John M | Contention resolution with counter rollover |
US20080130631A1 (en) * | 2006-10-05 | 2008-06-05 | Holt John M | Contention detection with modified message format |
US20100054254A1 (en) * | 2006-10-05 | 2010-03-04 | Holt John M | Asynchronous data transmission |
WO2008040076A1 (en) * | 2006-10-05 | 2008-04-10 | Waratek Pty Limited | Contention resolution with echo cancellation |
US8095616B2 (en) | 2006-10-05 | 2012-01-10 | Waratek Pty Ltd. | Contention detection |
US20080133861A1 (en) * | 2006-10-05 | 2008-06-05 | Holt John M | Silent memory reclamation |
WO2008040083A1 (en) * | 2006-10-05 | 2008-04-10 | Waratek Pty Limited | Adding one or more computers to a multiple computer system |
US8316190B2 (en) | 2007-04-06 | 2012-11-20 | Waratek Pty. Ltd. | Computer architecture and method of operation for multi-computer distributed processing having redundant array of independent systems with replicated memory and code striping |
KR101778825B1 (ko) | 2010-05-03 | 2017-09-14 | 메르크 파텐트 게엠베하 | 제형물 및 전자 소자 |
JP5625621B2 (ja) | 2010-08-25 | 2014-11-19 | 富士通株式会社 | 検出装置、方法、及びプログラム |
CN105490908A (zh) * | 2014-09-16 | 2016-04-13 | 中兴通讯股份有限公司 | 目标资源占用情况的处理方法及装置 |
EP3451259A1 (en) * | 2017-09-01 | 2019-03-06 | Unify Patente GmbH & Co. KG | Computer-implemented method of performing a real-time collaboration session, collaborative platform for performing real-time collaboration sessions, and collaborative chat post object |
CN110069243B (zh) * | 2018-10-31 | 2023-03-03 | 上海奥陶网络科技有限公司 | 一种java程序线程优化方法 |
Citations (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JPH01297759A (ja) * | 1988-05-26 | 1989-11-30 | Tokyo Electric Power Co Inc:The | ブロードキャストメモリ方式分散コンピュータシステム |
JPH02132543A (ja) * | 1988-11-12 | 1990-05-22 | Nec Corp | 情報処理装置 |
WO1995008809A2 (en) * | 1993-09-24 | 1995-03-30 | Oracle Corporation | Method and apparatus for data replication |
US5488723A (en) * | 1992-05-25 | 1996-01-30 | Cegelec | Software system having replicated objects and using dynamic messaging, in particular for a monitoring/control installation of redundant architecture |
WO2002044835A2 (en) * | 2000-11-28 | 2002-06-06 | Gingerich Gregory L | A method and system for software and hardware multiplicity |
US6625751B1 (en) * | 1999-08-11 | 2003-09-23 | Sun Microsystems, Inc. | Software fault tolerant computer system |
WO2003083614A2 (en) * | 2002-03-25 | 2003-10-09 | Eternal Systems, Inc. | Transparent consistent active replication of multithreaded application programs |
US20040073828A1 (en) * | 2002-08-30 | 2004-04-15 | Vladimir Bronstein | Transparent variable state mirroring |
Family Cites Families (7)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
ATE180586T1 (de) * | 1990-11-13 | 1999-06-15 | Ibm | Paralleles assoziativprozessor-system |
US5960087A (en) * | 1996-07-01 | 1999-09-28 | Sun Microsystems, Inc. | Distributed garbage collection system and method |
US6072953A (en) * | 1997-09-30 | 2000-06-06 | International Business Machines Corporation | Apparatus and method for dynamically modifying class files during loading for execution |
US6324587B1 (en) * | 1997-12-23 | 2001-11-27 | Microsoft Corporation | Method, computer program product, and data structure for publishing a data object over a store and forward transport |
US6662359B1 (en) * | 2000-07-20 | 2003-12-09 | International Business Machines Corporation | System and method for injecting hooks into Java classes to handle exception and finalization processing |
JP2002116917A (ja) * | 2000-10-05 | 2002-04-19 | Fujitsu Ltd | オブジェクト指向型プログラミング言語によるソース・プログラムをコンパイルするコンパイラ |
US7774750B2 (en) * | 2005-07-19 | 2010-08-10 | Microsoft Corporation | Common concurrency runtime |
-
2005
- 2005-04-22 EP EP05733669A patent/EP1763774B1/en active Active
- 2005-04-22 MX MXPA06012209A patent/MXPA06012209A/es active IP Right Grant
- 2005-04-22 JP JP2007508674A patent/JP2007534063A/ja active Pending
- 2005-04-22 JP JP2007508675A patent/JP2007534064A/ja active Pending
- 2005-04-22 BR BRPI0508929-8A patent/BRPI0508929A/pt not_active Application Discontinuation
- 2005-04-22 WO PCT/AU2005/000581 patent/WO2005103927A1/en active IP Right Grant
- 2005-04-22 CN CN201010247309.2A patent/CN101908001B/zh active Active
- 2005-04-22 CA CA2563900A patent/CA2563900C/en active Active
- 2005-04-22 EA EA200601942A patent/EA009926B1/ru not_active IP Right Cessation
- 2005-04-22 WO PCT/AU2005/000579 patent/WO2005103925A1/en active IP Right Grant
- 2005-04-22 WO PCT/AU2005/000580 patent/WO2005103926A1/en active Application Filing
- 2005-04-22 JP JP2007508677A patent/JP2007534066A/ja active Pending
- 2005-04-22 ZA ZA200608766A patent/ZA200608766B/xx unknown
- 2005-04-22 EP EP05733638A patent/EP1763772A4/en not_active Withdrawn
- 2005-04-22 WO PCT/AU2005/000578 patent/WO2005103924A1/en active Application Filing
- 2005-04-22 WO PCT/AU2005/000582 patent/WO2005103928A1/en active Application Filing
- 2005-04-22 KR KR1020067022016A patent/KR101209023B1/ko active IP Right Grant
- 2005-04-22 EP EP20110002408 patent/EP2341430A1/en not_active Withdrawn
- 2005-04-22 EP EP05733436A patent/EP1763771A4/en not_active Withdrawn
- 2005-04-22 NZ NZ550480A patent/NZ550480A/en unknown
- 2005-04-22 CN CN2005800184057A patent/CN1965308B/zh active Active
- 2005-04-22 EP EP05733639A patent/EP1763773A4/en not_active Withdrawn
- 2005-04-22 JP JP2007508676A patent/JP2007534065A/ja active Pending
-
2006
- 2006-10-15 IL IL178527A patent/IL178527A/en active IP Right Grant
Patent Citations (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JPH01297759A (ja) * | 1988-05-26 | 1989-11-30 | Tokyo Electric Power Co Inc:The | ブロードキャストメモリ方式分散コンピュータシステム |
JPH02132543A (ja) * | 1988-11-12 | 1990-05-22 | Nec Corp | 情報処理装置 |
US5488723A (en) * | 1992-05-25 | 1996-01-30 | Cegelec | Software system having replicated objects and using dynamic messaging, in particular for a monitoring/control installation of redundant architecture |
WO1995008809A2 (en) * | 1993-09-24 | 1995-03-30 | Oracle Corporation | Method and apparatus for data replication |
US6625751B1 (en) * | 1999-08-11 | 2003-09-23 | Sun Microsystems, Inc. | Software fault tolerant computer system |
WO2002044835A2 (en) * | 2000-11-28 | 2002-06-06 | Gingerich Gregory L | A method and system for software and hardware multiplicity |
WO2003083614A2 (en) * | 2002-03-25 | 2003-10-09 | Eternal Systems, Inc. | Transparent consistent active replication of multithreaded application programs |
US20040073828A1 (en) * | 2002-08-30 | 2004-04-15 | Vladimir Bronstein | Transparent variable state mirroring |
Also Published As
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US7844665B2 (en) | Modified computer architecture having coordinated deletion of corresponding replicated memory locations among plural computers | |
CA2563900C (en) | Modified computer architecture with coordinated objects | |
US20060020913A1 (en) | Multiple computer architecture with synchronization | |
US20060095483A1 (en) | Modified computer architecture with finalization of objects | |
US20050262513A1 (en) | Modified computer architecture with initialization of objects | |
US20060265704A1 (en) | Computer architecture and method of operation for multi-computer distributed processing with synchronization | |
AU2005236087B2 (en) | Modified computer architecture with coordinated objects | |
AU2005236086A1 (en) | Multiple computer architecture with synchronization | |
AU2005236088B2 (en) | Modified computer architecture with finalization of objects | |
AU2005236085A1 (en) | Modified computer architecture with initialization of objects | |
AU2005236089A1 (en) | Multiple computer architecture with replicated memory fields | |
AU2006238334A1 (en) | Modified computer architecture for a computer to operate in a multiple computer system |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
A621 | Written request for application examination |
Free format text: JAPANESE INTERMEDIATE CODE: A621 Effective date: 20080404 |
|
A131 | Notification of reasons for refusal |
Free format text: JAPANESE INTERMEDIATE CODE: A131 Effective date: 20100921 |
|
A521 | Request for written amendment filed |
Free format text: JAPANESE INTERMEDIATE CODE: A523 Effective date: 20101221 |
|
A02 | Decision of refusal |
Free format text: JAPANESE INTERMEDIATE CODE: A02 Effective date: 20110131 |
|
A521 | Request for written amendment filed |
Free format text: JAPANESE INTERMEDIATE CODE: A523 Effective date: 20110531 |
|
A911 | Transfer to examiner for re-examination before appeal (zenchi) |
Free format text: JAPANESE INTERMEDIATE CODE: A911 Effective date: 20110606 |
|
A912 | Re-examination (zenchi) completed and case transferred to appeal board |
Free format text: JAPANESE INTERMEDIATE CODE: A912 Effective date: 20110701 |