Skip to content

Commit

Permalink
using static local variable instead of global variables for globalMutex
Browse files Browse the repository at this point in the history
  • Loading branch information
guoyiteng committed Dec 18, 2019
1 parent 3ee3537 commit 4abbe18
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 19 deletions.
7 changes: 3 additions & 4 deletions compiler/src/jlang/extension/JLangClassDeclExt.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.stream.Stream;

import static jlang.extension.JLangSynchronizedExt.buildMonitorFunc;
import static jlang.extension.JLangSynchronizedExt.buildMonitorFuncWithGlobalMutex;
import static jlang.util.Constants.REGISTER_CLASS_FUNC;
import static jlang.util.Constants.RUNTIME_ARRAY;
import static org.bytedeco.javacpp.LLVM.*;
Expand Down Expand Up @@ -192,9 +193,7 @@ public static void buildClassLoadingFunc(LLVMTranslator v, ClassType ct, ClassBo

Runnable buildBody = () -> {
// Synchronize the class loading function.
LLVMValueRef globalMutexPtr = v.utils.getGlobal(Constants.GLOBAL_MUTEX_OBJECT, v.utils.toLL(v.ts.Object()));
LLVMValueRef globalMutex = LLVMBuildLoad(v.builder, globalMutexPtr, "load.classLoad");
buildMonitorFunc(v, Constants.MONITOR_ENTER, globalMutex);
buildMonitorFuncWithGlobalMutex(v, Constants.MONITOR_ENTER);

// Allocate and store a new java.lang.Class instance.
// Note that we do not call any constructors for the allocated class objects.
Expand Down Expand Up @@ -252,7 +251,7 @@ public static void buildClassLoadingFunc(LLVMTranslator v, ClassType ct, ClassBo
}
}

buildMonitorFunc(v, Constants.MONITOR_EXIT, globalMutex);
buildMonitorFuncWithGlobalMutex(v, Constants.MONITOR_EXIT);

// Return the loaded class.
LLVMBuildRet(v.builder, clazz);
Expand Down
11 changes: 11 additions & 0 deletions compiler/src/jlang/extension/JLangSynchronizedExt.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
package jlang.extension;

import jlang.ast.JLangExt;
import jlang.util.Constants;
import jlang.visit.LLVMTranslator;
import org.bytedeco.javacpp.LLVM.LLVMBasicBlockRef;
import org.bytedeco.javacpp.LLVM.LLVMTypeRef;
import org.bytedeco.javacpp.LLVM.LLVMValueRef;
import polyglot.ast.Node;
Expand All @@ -24,6 +26,15 @@ public Node leaveTranslateLLVM(LLVMTranslator v) {
return super.leaveTranslateLLVM(v);
}

public static void buildMonitorFuncWithGlobalMutex(LLVMTranslator v, String op) {
LLVMTypeRef getGlobalMutexFuncType = v.utils.functionType(
v.utils.toLL(v.ts.Object())
);
LLVMValueRef getGlobalMutexFunc = v.utils.getFunction(Constants.GET_GLOBAL_MUTEX_OBJECT, getGlobalMutexFuncType);
LLVMValueRef globalMutex = v.utils.buildFunCall(getGlobalMutexFunc);
buildMonitorFunc(v, op, globalMutex);
}

public static void buildMonitorFunc(LLVMTranslator v, String op, LLVMValueRef syncObj) {
LLVMValueRef cast = LLVMBuildBitCast(v.builder, syncObj, v.utils.toLL(v.ts.Object()), "cast_l");
LLVMTypeRef monitorFuncType = v.utils.functionType(
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/jlang/util/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class Constants {
public static final String RESUME_UNWIND_EXCEPTION = "_Unwind_Resume";
public static final String MONITOR_ENTER = "jni_MonitorEnter";
public static final String MONITOR_EXIT = "jni_MonitorExit";
public static final String GLOBAL_MUTEX_OBJECT = "Polyglot_native_GlobalMutexObject";
public static final String GET_GLOBAL_MUTEX_OBJECT = "getGlobalMutexObject";

public static final Set<String> NON_INVOKE_FUNCTIONS = new HashSet<>(CollectionUtil.list(
CALLOC, CREATE_EXCEPTION, EXTRACT_EXCEPTION
Expand Down
7 changes: 3 additions & 4 deletions compiler/src/jlang/util/LLVMUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.stream.IntStream;

import static jlang.extension.JLangSynchronizedExt.buildMonitorFunc;
import static jlang.extension.JLangSynchronizedExt.buildMonitorFuncWithGlobalMutex;
import static org.bytedeco.javacpp.LLVM.*;

/**
Expand Down Expand Up @@ -805,9 +806,7 @@ public LLVMValueRef buildGlobalCStr(String str) {
/** Emits a check to ensure that the given class has been loaded by the runtime. */
public void buildClassLoadCheck(ClassType ct) {
// Synchronize the class loading function.
LLVMValueRef globalMutexPtr = v.utils.getGlobal(Constants.GLOBAL_MUTEX_OBJECT, v.utils.toLL(v.ts.Object()));
LLVMValueRef globalMutex = LLVMBuildLoad(v.builder, globalMutexPtr, "load.classLoad");
buildMonitorFunc(v, Constants.MONITOR_ENTER, globalMutex);
buildMonitorFuncWithGlobalMutex(v, Constants.MONITOR_ENTER);

LLVMBasicBlockRef loadClass = v.utils.buildBlock("load.class");
LLVMBasicBlockRef end = v.utils.buildBlock("continue");
Expand All @@ -827,7 +826,7 @@ public void buildClassLoadCheck(ClassType ct) {

LLVMPositionBuilderAtEnd(v.builder, end);

buildMonitorFunc(v, Constants.MONITOR_EXIT, globalMutex);
buildMonitorFuncWithGlobalMutex(v, Constants.MONITOR_EXIT);
}

/**
Expand Down
1 change: 1 addition & 0 deletions runtime/linux_version.map
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ SUNWprivate_1.1 {
__createInterfaceTables;
__java_personality_v0;
__GC_malloc;
getGlobalMutexObject;
local:
*;
};
Expand Down
6 changes: 2 additions & 4 deletions runtime/native/class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -690,12 +690,11 @@ jclass LoadJavaClassFromLib(const char *name) {
* function will be invoked. The class name is in the format java.lang.Class
*/
jclass FindClass(const char *name) {
Monitor::Instance().enter(nullptr);
ScopedLock scopedLock(Monitor::Instance().globalMutex());
jclass clazz = GetJavaClassFromName(name);
if (clazz == nullptr) {
clazz = LoadJavaClassFromLib(name);
}
Monitor::Instance().exit(nullptr);
return clazz;
}

Expand All @@ -704,11 +703,10 @@ jclass FindClass(const char *name) {
* function will be invoked. The class name is in the format java/lang/Class
*/
jclass FindClassFromPathName(const char *name) {
Monitor::Instance().enter(nullptr);
ScopedLock scopedLock(Monitor::Instance().globalMutex());
jclass clazz = GetJavaClassFromPathName(name);
if (clazz == nullptr) {
clazz = LoadJavaClassFromLib(name);
}
Monitor::Instance().exit(nullptr);
return clazz;
}
5 changes: 5 additions & 0 deletions runtime/native/factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "class.h"
#include "rep.h"
#include "monitor.h"

#include <jni.h>
#include <string.h>
Expand Down Expand Up @@ -66,6 +67,8 @@ jstring CreateJavaString(jcharArray chars) {
}

jobject CreateJavaObject(jclass clazz) {
ScopedLock lock(Monitor::Instance().globalMutex());

auto info = GetJavaClassInfo(clazz);
// TODO set exception (class is interface or abstract)
if (info == NULL || info->cdv == NULL) {
Expand All @@ -81,6 +84,8 @@ jobject CreateJavaObject(jclass clazz) {

jobject CloneJavaObject(jobject obj) {
// TODO set exception if class is not cloneable
ScopedLock lock(Monitor::Instance().globalMutex());

auto objRep = Unwrap(obj);
auto cdv = objRep->Cdv();
auto cls = cdv->Class()->Wrap();
Expand Down
8 changes: 2 additions & 6 deletions runtime/native/monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,14 @@ static void initSyncVars(jobject obj) {
// A fake object to hold the sync_var of class loading function.
// The class loading code could utilize this global object to ensure that
// every class is only initilized by one thread once.
JObjectRep __Polyglot_native_GlobalMutexObject;

static jobject getGlobalMutexObject() {
extern "C" jobject getGlobalMutexObject() {
static JObjectRep __Polyglot_native_GlobalMutexObject;
if (__Polyglot_native_GlobalMutexObject.SyncVars() == nullptr) {
initSyncVars(__Polyglot_native_GlobalMutexObject.Wrap());
}
return __Polyglot_native_GlobalMutexObject.Wrap();
}

jobject Polyglot_native_GlobalMutexObject = getGlobalMutexObject();


Monitor::Monitor() {
if (pthread_mutex_init(&mutex, nullptr) != 0) {
perror("mutex init failed");
Expand Down

0 comments on commit 4abbe18

Please sign in to comment.