[vmkit-commits] [vmkit] r180312 - Fixed monitorExit() bug when synchronization object was set to null between monitorEnter() and monitorExit().
Peter Senna Tschudin
peter.senna at gmail.com
Thu Apr 25 09:54:46 PDT 2013
Author: peter.senna
Date: Thu Apr 25 11:53:09 2013
New Revision: 180312
URL: http://llvm.org/viewvc/llvm-project?rev=180312&view=rev
Log:
Fixed monitorExit() bug when synchronization object was set to null between monitorEnter() and monitorExit().
(cherry picked from commit 0ff6ffaf2411c7e6e5034b97cfd728c5cad03784)
Modified:
vmkit/trunk/include/vmkit/UTF8.h
vmkit/trunk/lib/j3/Compiler/JavaJIT.cpp
vmkit/trunk/lib/j3/Compiler/JavaJITOpcodes.cpp
vmkit/trunk/lib/j3/VMCore/JavaClass.cpp
vmkit/trunk/lib/j3/VMCore/JavaClass.h
vmkit/trunk/lib/vmkit/Runtime/UTF8.cpp
Modified: vmkit/trunk/include/vmkit/UTF8.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/vmkit/UTF8.h?rev=180312&r1=180311&r2=180312&view=diff
==============================================================================
--- vmkit/trunk/include/vmkit/UTF8.h (original)
+++ vmkit/trunk/include/vmkit/UTF8.h Thu Apr 25 11:53:09 2013
@@ -67,6 +67,7 @@ public:
friend std::ostream& operator << (std::ostream&, const UTF8&);
void dump() const __attribute__((noinline));
int compare(const char *) const;
+ std::string& toString(std::string& buffer) const;
};
extern "C" const UTF8 TombstoneKey;
Modified: vmkit/trunk/lib/j3/Compiler/JavaJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/Compiler/JavaJIT.cpp?rev=180312&r1=180311&r2=180312&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/Compiler/JavaJIT.cpp (original)
+++ vmkit/trunk/lib/j3/Compiler/JavaJIT.cpp Thu Apr 25 11:53:09 2013
@@ -12,6 +12,8 @@
#define JNJVM_COMPILE 0
#define JNJVM_EXECUTE 0
+#include <string>
+#include <sstream>
#include <cstring>
#include <llvm/Constants.h>
@@ -43,6 +45,7 @@
using namespace j3;
using namespace llvm;
+using namespace std;
void JavaJIT::updateStackInfo(Opinfo& info) {
if (stackSize()) {
@@ -291,13 +294,13 @@ llvm::Value* JavaJIT::getMutatorThreadPt
currentBlock);
threadId = BinaryOperator::CreateAnd(threadId, intrinsics->constantThreadIDMask,
"", currentBlock);
- threadId = new IntToPtrInst(threadId, intrinsics->MutatorThreadType, "", currentBlock);
+ threadId = new IntToPtrInst(threadId, intrinsics->MutatorThreadType, "MutatorThreadPtr", currentBlock);
return threadId;
}
llvm::Value* JavaJIT::getJavaThreadPtr(llvm::Value* mutatorThreadPtr) {
- return new BitCastInst(mutatorThreadPtr, intrinsics->JavaThreadType, "", currentBlock);
+ return new BitCastInst(mutatorThreadPtr, intrinsics->JavaThreadType, "JavaThreadPtr", currentBlock);
}
llvm::Value* JavaJIT::getIsolateIDPtr(llvm::Value* mutatorThreadPtr) {
@@ -305,7 +308,7 @@ llvm::Value* JavaJIT::getIsolateIDPtr(ll
intrinsics->OffsetThreadInMutatorThreadConstant,
intrinsics->OffsetIsolateIDInThreadConstant };
- return GetElementPtrInst::Create(mutatorThreadPtr, GEP, "", currentBlock);
+ return GetElementPtrInst::Create(mutatorThreadPtr, GEP, "isolateIDPtr", currentBlock);
}
llvm::Value* JavaJIT::getVMPtr(llvm::Value* mutatorThreadPtr) {
@@ -313,7 +316,7 @@ llvm::Value* JavaJIT::getVMPtr(llvm::Val
intrinsics->OffsetThreadInMutatorThreadConstant,
intrinsics->OffsetVMInThreadConstant };
- return GetElementPtrInst::Create(mutatorThreadPtr, GEP, "", currentBlock);
+ return GetElementPtrInst::Create(mutatorThreadPtr, GEP, "VMPtr", currentBlock);
}
llvm::Value* JavaJIT::getDoYieldPtr(llvm::Value* mutatorThreadPtr) {
@@ -321,21 +324,21 @@ llvm::Value* JavaJIT::getDoYieldPtr(llvm
intrinsics->OffsetThreadInMutatorThreadConstant,
intrinsics->OffsetDoYieldInThreadConstant };
- return GetElementPtrInst::Create(mutatorThreadPtr, GEP, "", currentBlock);
+ return GetElementPtrInst::Create(mutatorThreadPtr, GEP, "doYieldPtr", currentBlock);
}
llvm::Value* JavaJIT::getJNIEnvPtr(llvm::Value* javaThreadPtr) {
Value* GEP[2] = { intrinsics->constantZero,
intrinsics->OffsetJNIInJavaThreadConstant };
- return GetElementPtrInst::Create(javaThreadPtr, GEP, "", currentBlock);
+ return GetElementPtrInst::Create(javaThreadPtr, GEP, "JNIPtr", currentBlock);
}
llvm::Value* JavaJIT::getJavaExceptionPtr(llvm::Value* javaThreadPtr) {
Value* GEP[2] = { intrinsics->constantZero,
intrinsics->OffsetJavaExceptionInJavaThreadConstant };
- return GetElementPtrInst::Create(javaThreadPtr, GEP, "", currentBlock);
+ return GetElementPtrInst::Create(javaThreadPtr, GEP, "pendingExceptionPtr", currentBlock);
}
static llvm::Function* GetNativeCallee(JavaLLVMCompiler* TheCompiler,
@@ -343,9 +346,10 @@ static llvm::Function* GetNativeCallee(J
LLVMSignatureInfo* LSI =
TheCompiler->getSignatureInfo(compilingMethod->getSignature());
FunctionType* FTy = LSI->getNativeStubType();
+ string methName;
Function* callee = Function::Create(FTy,
GlobalValue::ExternalLinkage,
- "",
+ compilingMethod->getName(methName, true),
TheCompiler->getLLVMModule());
std::vector<Value*> args;
Function::arg_iterator i = callee->arg_begin();
@@ -648,7 +652,7 @@ llvm::Value* JavaJIT::objectToHeader(Val
obj = new PtrToIntInst(obj, intrinsics->pointerSizeType, "", currentBlock);
Value* d = ConstantInt::get(intrinsics->pointerSizeType, gcHeader::hiddenHeaderSize());
obj = BinaryOperator::CreateSub(obj, d, "", currentBlock);
- return new IntToPtrInst(obj, intrinsics->ObjectHeaderType, "", currentBlock);
+ return new IntToPtrInst(obj, intrinsics->ObjectHeaderType, "objectHeader", currentBlock);
}
void JavaJIT::monitorEnter(Value* obj) {
@@ -689,6 +693,21 @@ void JavaJIT::monitorEnter(Value* obj) {
}
void JavaJIT::monitorExit(Value* obj) {
+ /*
+ obj should not be null if we are here.
+ If obj was null when monitorEnter() was run, then monitorEnter() should have
+ thrown an exception. If it was not null then, and it is null now, it must have
+ been reset by the GC (it became a stale reference) between monitorEnter() and
+ monitorExit(). In this case, just get out of the synchronize block silently.
+ */
+ BasicBlock* nonNullObjBlock = createBasicBlock("monitorExit_nonNullObj");
+ BasicBlock* EndBlock = createBasicBlock("monitorExit_End");
+
+ Value* test = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, obj, intrinsics->JavaObjectNullConstant, "isObjectNull");
+ BranchInst::Create(EndBlock, nonNullObjBlock, test, currentBlock);
+
+ currentBlock = nonNullObjBlock;
+
Value* lockPtr = objectToHeader(obj);
Value* lock = new LoadInst(lockPtr, "", currentBlock);
@@ -719,17 +738,16 @@ void JavaJIT::monitorExit(Value* obj) {
Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, atomic,
oldValMask, "");
- BasicBlock* OK = createBasicBlock("unsynchronize passed");
- BasicBlock* NotOK = createBasicBlock("unsynchronize did not pass");
+ BasicBlock* LockFreeCASFailed = createBasicBlock("Lock-Free CAS Failed");
- BranchInst::Create(OK, NotOK, cmp, currentBlock);
+ BranchInst::Create(EndBlock, LockFreeCASFailed, cmp, currentBlock);
// The atomic cas did not work.
- currentBlock = NotOK;
+ currentBlock = LockFreeCASFailed;
CallInst::Create(intrinsics->ReleaseObjectFunction, obj, "", currentBlock);
- BranchInst::Create(OK, currentBlock);
+ BranchInst::Create(EndBlock, currentBlock);
- currentBlock = OK;
+ currentBlock = EndBlock;
}
void JavaJIT::beginSynchronize() {
@@ -965,13 +983,23 @@ Instruction* JavaJIT::inlineCompile(Basi
return endNode;
}
+static char* setInstructionName(char *s, size_t maxlen, const char * format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ vsnprintf(s, maxlen, format, args);
+ va_end(args);
+ return s;
+}
+
llvm::Function* JavaJIT::javaCompile() {
PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "compiling %s.%s\n",
UTF8Buffer(compilingClass->name).cString(),
UTF8Buffer(compilingMethod->name).cString());
+ string methName, methNameLink;
DbgSubprogram = TheCompiler->getDebugFactory()->createFunction(
- DIDescriptor(), "", "", DIFile(), 0, DIType(), false, false, 0);
+ DIDescriptor(), compilingMethod->getName(methName, false), compilingMethod->getName(methNameLink, true), DIFile(), 0, DIType(), false, false, 0);
JavaAttribute* codeAtt = compilingMethod->lookupAttribute(JavaAttribute::codeAttribute);
@@ -996,6 +1024,9 @@ llvm::Function* JavaJIT::javaCompile() {
Function* func = llvmFunction;
+ const size_t instNameLen = 4096;
+ char instName[instNameLen];
+
currentBlock = createBasicBlock("start");
endExceptionBlock = createBasicBlock("endExceptionBlock");
unifiedUnreachable = createBasicBlock("unifiedUnreachable");
@@ -1009,7 +1040,7 @@ llvm::Function* JavaJIT::javaCompile() {
Instruction* returnValue = NULL;
if (returnType == intrinsics->JavaObjectType &&
TheCompiler->useCooperativeGC()) {
- returnValue = new AllocaInst(intrinsics->JavaObjectType, "",
+ returnValue = new AllocaInst(intrinsics->JavaObjectType, "returnValue",
currentBlock);
Instruction* cast =
new BitCastInst(returnValue, intrinsics->ptrPtrType, "", currentBlock);
@@ -1019,29 +1050,27 @@ llvm::Function* JavaJIT::javaCompile() {
}
for (int i = 0; i < maxLocals; i++) {
- intLocals.push_back(new AllocaInst(Type::getInt32Ty(*llvmContext), "", currentBlock));
+ intLocals.push_back(new AllocaInst(Type::getInt32Ty(*llvmContext), setInstructionName(instName, instNameLen, "int_%d", i), currentBlock));
new StoreInst(Constant::getNullValue(Type::getInt32Ty(*llvmContext)), intLocals.back(), false, currentBlock);
- doubleLocals.push_back(new AllocaInst(Type::getDoubleTy(*llvmContext), "", currentBlock));
+ doubleLocals.push_back(new AllocaInst(Type::getDoubleTy(*llvmContext), setInstructionName(instName, instNameLen, "double_%d", i), currentBlock));
new StoreInst(Constant::getNullValue(Type::getDoubleTy(*llvmContext)), doubleLocals.back(), false, currentBlock);
- longLocals.push_back(new AllocaInst(Type::getInt64Ty(*llvmContext), "", currentBlock));
+ longLocals.push_back(new AllocaInst(Type::getInt64Ty(*llvmContext), setInstructionName(instName, instNameLen, "long_%d", i), currentBlock));
new StoreInst(Constant::getNullValue(Type::getInt64Ty(*llvmContext)), longLocals.back(), false, currentBlock);
- floatLocals.push_back(new AllocaInst(Type::getFloatTy(*llvmContext), "", currentBlock));
+ floatLocals.push_back(new AllocaInst(Type::getFloatTy(*llvmContext), setInstructionName(instName, instNameLen, "float_%d", i), currentBlock));
new StoreInst(Constant::getNullValue(Type::getFloatTy(*llvmContext)), floatLocals.back(), false, currentBlock);
- objectLocals.push_back(new AllocaInst(intrinsics->JavaObjectType, "",
- currentBlock));
+ objectLocals.push_back(new AllocaInst(intrinsics->JavaObjectType, setInstructionName(instName, instNameLen, "object_%d", i), currentBlock));
// The GCStrategy will already initialize the value.
if (!TheCompiler->useCooperativeGC())
new StoreInst(Constant::getNullValue(intrinsics->JavaObjectType), objectLocals.back(), false, currentBlock);
}
for (int i = 0; i < maxStack; i++) {
- objectStack.push_back(new AllocaInst(intrinsics->JavaObjectType, "",
- currentBlock));
+ objectStack.push_back(new AllocaInst(intrinsics->JavaObjectType, setInstructionName(instName, instNameLen, "stack_object_%d", i), currentBlock));
addHighLevelType(objectStack.back(), upcalls->OfObject);
- intStack.push_back(new AllocaInst(Type::getInt32Ty(*llvmContext), "", currentBlock));
- doubleStack.push_back(new AllocaInst(Type::getDoubleTy(*llvmContext), "", currentBlock));
- longStack.push_back(new AllocaInst(Type::getInt64Ty(*llvmContext), "", currentBlock));
- floatStack.push_back(new AllocaInst(Type::getFloatTy(*llvmContext), "", currentBlock));
+ intStack.push_back(new AllocaInst(Type::getInt32Ty(*llvmContext), setInstructionName(instName, instNameLen, "stack_int_%d", i), currentBlock));
+ doubleStack.push_back(new AllocaInst(Type::getDoubleTy(*llvmContext), setInstructionName(instName, instNameLen, "stack_double_%d", i), currentBlock));
+ longStack.push_back(new AllocaInst(Type::getInt64Ty(*llvmContext), setInstructionName(instName, instNameLen, "stack_long_%d", i), currentBlock));
+ floatStack.push_back(new AllocaInst(Type::getFloatTy(*llvmContext), setInstructionName(instName, instNameLen, "stack_float_%d", i), currentBlock));
}
uint32 index = 0;
@@ -1099,14 +1128,10 @@ llvm::Function* JavaJIT::javaCompile() {
}
#endif
- if (compilingMethod->name->compare("ijvm_tests_Runner_loop") == 0) {
- llvmFunction->dump();
- }
-
nbHandlers = readExceptionTable(reader, codeLen);
if (nbHandlers != 0) {
jmpBuffer = new AllocaInst(ArrayType::get(Type::getInt8Ty(*llvmContext), sizeof(vmkit::ExceptionBuffer)), "", currentBlock);
- jmpBuffer = new BitCastInst(jmpBuffer, intrinsics->ptrType, "", currentBlock);
+ jmpBuffer = new BitCastInst(jmpBuffer, intrinsics->ptrType, "exceptionSavePoint", currentBlock);
}
reader.cursor = start;
@@ -1201,10 +1226,10 @@ llvm::Function* JavaJIT::javaCompile() {
currentBlock->eraseFromParent();
} else {
if (nbHandlers != 0) {
- BasicBlock* ifNormal = createBasicBlock("");
- BasicBlock* ifException = createBasicBlock("");
+ BasicBlock* ifNormal = createBasicBlock("No exception was thrown");
+ BasicBlock* ifException = createBasicBlock("Rethrow Exception");
Value* javaExceptionPtr = getJavaExceptionPtr(getJavaThreadPtr(getMutatorThreadPtr()));
- Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock);
+ Value* obj = new LoadInst(javaExceptionPtr, "pendingException", currentBlock);
Value* test = new ICmpInst(*currentBlock, ICmpInst::ICMP_NE, obj, intrinsics->JavaObjectNullConstant, "");
BranchInst::Create(ifException, ifNormal, test, currentBlock);
@@ -1350,16 +1375,15 @@ void JavaJIT::JITVerifyNull(Value* obj)
Instruction* VT = new LoadInst(VTPtr, "", true, currentBlock);
VT->setDebugLoc(DebugLoc::get(currentBytecodeIndex, 1, DbgSubprogram));
} else {
- Constant* zero = intrinsics->JavaObjectNullConstant;
- Value* test = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, obj, zero, "");
+ Value* test = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, obj, intrinsics->JavaObjectNullConstant, "");
- BasicBlock* exit = createBasicBlock("verifyNullExit");
- BasicBlock* cont = createBasicBlock("verifyNullCont");
+ BasicBlock* nullObjBlock = createBasicBlock("object is null");
+ BasicBlock* notNullObjBlock = createBasicBlock("object is not null");
- BranchInst::Create(exit, cont, test, currentBlock);
- currentBlock = exit;
+ BranchInst::Create(nullObjBlock, notNullObjBlock, test, currentBlock);
+ currentBlock = nullObjBlock;
throwRuntimeException(intrinsics->NullPointerExceptionFunction, 0, 0);
- currentBlock = cont;
+ currentBlock = notNullObjBlock;
}
}
}
@@ -2320,8 +2344,8 @@ Instruction* JavaJIT::invoke(Value *F, s
BasicBlock* ifException = NULL;
if (jmpBuffer != NULL) {
- BasicBlock* doCall = createBasicBlock("");
- ifException = createBasicBlock("");
+ BasicBlock* doCall = createBasicBlock("Perform call");
+ ifException = createBasicBlock("Exception thrown");
Instruction* check = CallInst::Create(intrinsics->SetjmpFunction, jmpBuffer, "", currentBlock);
check = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, check, intrinsics->constantZero, "");
BranchInst::Create(doCall, ifException, check, currentBlock);
@@ -2394,7 +2418,7 @@ void JavaJIT::throwRuntimeException(llvm
}
void JavaJIT::throwRuntimeException(llvm::Function* F, Value** args, uint32 nbArgs) {
- Instruction* obj = CallInst::Create(F, ArrayRef<Value*>(args, nbArgs), "", currentBlock);
+ Instruction* obj = CallInst::Create(F, ArrayRef<Value*>(args, nbArgs), "exceptionObject", currentBlock);
DebugLoc DL = CreateLocation();
obj->setDebugLoc(DL);
throwException(obj, false);
@@ -2524,9 +2548,9 @@ unsigned JavaJIT::readExceptionTable(Rea
// Get the Java exception.
Value* javaExceptionPtr = getJavaExceptionPtr(getJavaThreadPtr(getMutatorThreadPtr()));
- Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock);
+ Value* obj = new LoadInst(javaExceptionPtr, "pendingException", currentBlock);
- Value* objVT = CallInst::Create(intrinsics->GetVTFunction, obj, "",
+ Value* objVT = CallInst::Create(intrinsics->GetVTFunction, obj, "objectVT",
currentBlock);
uint32 depth = cur->catchClass->virtualVT->depth;
@@ -2537,16 +2561,16 @@ unsigned JavaJIT::readExceptionTable(Rea
Value* classArgs[2] = { objVT, VTVar };
cmp = CallInst::Create(intrinsics->IsSecondaryClassFunction,
- classArgs, "", currentBlock);
+ classArgs, "isSecondaryClass", currentBlock);
} else {
Value* inDisplay = CallInst::Create(intrinsics->GetDisplayFunction,
- objVT, "", currentBlock);
+ objVT, "objectDisplay", currentBlock);
Value* displayArgs[2] = { inDisplay, depthCl };
Value* VTInDisplay = CallInst::Create(intrinsics->GetVTInDisplayFunction,
- displayArgs, "", currentBlock);
+ displayArgs, "objectVTInDisplay", currentBlock);
cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, VTInDisplay, VTVar,
"");
Modified: vmkit/trunk/lib/j3/Compiler/JavaJITOpcodes.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/Compiler/JavaJITOpcodes.cpp?rev=180312&r1=180311&r2=180312&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/Compiler/JavaJITOpcodes.cpp (original)
+++ vmkit/trunk/lib/j3/Compiler/JavaJITOpcodes.cpp Thu Apr 25 11:53:09 2013
@@ -134,7 +134,7 @@ void JavaJIT::compileOpcodes(Reader& rea
if (opinfo->handler) {
// If it's a handler, put the exception object in the stack.
Value* javaExceptionPtr = getJavaExceptionPtr(getJavaThreadPtr(getMutatorThreadPtr()));
- Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock);
+ Value* obj = new LoadInst(javaExceptionPtr, "pendingException", currentBlock);
new StoreInst(obj, objectStack[0], "", currentBlock);
// And clear the exception.
new StoreInst(intrinsics->JavaObjectNullConstant, javaExceptionPtr, currentBlock);
@@ -2303,7 +2303,9 @@ void JavaJIT::compileOpcodes(Reader& rea
case MONITOREXIT : {
bool thisReference = isThisReference(currentStackIndex - 1);
Value* obj = pop();
- if (!thisReference) JITVerifyNull(obj);
+ // NOTE: monitorExit() should NOT throw an exception if object is null.
+ // See monitorExit() implementation.
+ // if (!thisReference) JITVerifyNull(obj);
monitorExit(obj);
break;
}
Modified: vmkit/trunk/lib/j3/VMCore/JavaClass.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaClass.cpp?rev=180312&r1=180311&r2=180312&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaClass.cpp (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaClass.cpp Thu Apr 25 11:53:09 2013
@@ -1765,6 +1765,27 @@ void Class::broadcastClass() {
JavaObject::notifyAll(delegatee);
}
+std::string& CommonClass::getName(std::string& nameBuffer, bool linkageName) const
+{
+ name->toString(nameBuffer);
+
+ for (size_t i=0; i < name->size; ++i) {
+ if (name->elements[i] == '/')
+ nameBuffer[i] = linkageName ? '_' : '.';
+ }
+
+ return nameBuffer;
+}
+
+std::string& JavaMethod::getName(std::string& nameBuffer, bool linkageName) const
+{
+ classDef->getName(nameBuffer, linkageName);
+ nameBuffer += linkageName ? '_' : '.';
+
+ string methName;
+ return nameBuffer += name->toString(methName);
+}
+
std::ostream& j3::operator << (std::ostream& os, const JavaMethod& m)
{
return os << *m.classDef->name << '.' << *m.name << " (" << *m.type << ')';
Modified: vmkit/trunk/lib/j3/VMCore/JavaClass.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaClass.h?rev=180312&r1=180311&r2=180312&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaClass.h (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaClass.h Thu Apr 25 11:53:09 2013
@@ -234,6 +234,8 @@ public:
const UTF8* getName() const { return name; }
Class* getSuper() const { return super; }
+ std::string& getName(std::string& nameBuffer, bool linkageName = false) const;
+
/// isArray - Is the class an array class?
///
bool isArray() const {
@@ -1107,6 +1109,7 @@ public:
JavaMethod_DECL_INVOKE(double, Double)
JavaMethod_DECL_INVOKE(JavaObject*, JavaObject)
+ std::string& getName(std::string& nameBuffer, bool linkageName = false) const;
friend std::ostream& operator << (std::ostream&, const JavaMethod&);
void dump() const __attribute__((noinline));
Modified: vmkit/trunk/lib/vmkit/Runtime/UTF8.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/vmkit/Runtime/UTF8.cpp?rev=180312&r1=180311&r2=180312&view=diff
==============================================================================
--- vmkit/trunk/lib/vmkit/Runtime/UTF8.cpp (original)
+++ vmkit/trunk/lib/vmkit/Runtime/UTF8.cpp Thu Apr 25 11:53:09 2013
@@ -52,6 +52,16 @@ int UTF8::compare(const char *s) const
return diff;
}
+std::string& UTF8::toString(std::string& buffer) const
+{
+ buffer.resize(size);
+
+ for (ssize_t i = 0; i < size; ++i)
+ buffer[i] = (std::string::value_type)(elements[i]);
+
+ return buffer;
+}
+
std::ostream& operator << (std::ostream& os, const UTF8& utf8)
{
for (ssize_t i = 0; i < utf8.size; ++i)
More information about the vmkit-commits
mailing list