[vmkit-commits] [vmkit] r198877 - Debugging outside j3codegen. Better debug stack and locals.

Gael Thomas gael.thomas at lip6.fr
Thu Jan 9 09:51:54 PST 2014


Author: gthomas
Date: Thu Jan  9 11:51:54 2014
New Revision: 198877

URL: http://llvm.org/viewvc/llvm-project?rev=198877&view=rev
Log:
Debugging outside j3codegen. Better debug stack and locals.

Added:
    vmkit/branches/mcjit/lib/j3/vm/j3codegen-debug.cc
Modified:
    vmkit/branches/mcjit/include/j3/j3codegen.h
    vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc
    vmkit/branches/mcjit/lib/j3/vm/j3utf16.cc

Modified: vmkit/branches/mcjit/include/j3/j3codegen.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3codegen.h?rev=198877&r1=198876&r2=198877&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3codegen.h (original)
+++ vmkit/branches/mcjit/include/j3/j3codegen.h Thu Jan  9 11:51:54 2014
@@ -70,6 +70,7 @@ namespace j3 {
 
 		llvm::MDNode*          dbgInfo;
 		uint32_t               javaPC;
+		uint32_t               bc;
 
 		J3CodeGenVar           locals;
 		J3CodeGenVar           stack;
@@ -168,6 +169,9 @@ namespace j3 {
 		static void         echoDebugEnter(uint32_t isLeave, const char* msg, ...);
 		static void         echoDebugExecute(uint32_t level, const char* msg, ...);
 		static void         echoElement(uint32_t level, uint32_t type, uintptr_t elmt);
+		void                genEchoElement(const char* msg, uint32_t idx, llvm::Value* val);
+		void                genDebugOpcode();
+		void                genDebugEnterLeave(bool isLeave);
 
 #define _x(name, id)														\
 		llvm::Function* name;

Added: vmkit/branches/mcjit/lib/j3/vm/j3codegen-debug.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3codegen-debug.cc?rev=198877&view=auto
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3codegen-debug.cc (added)
+++ vmkit/branches/mcjit/lib/j3/vm/j3codegen-debug.cc Thu Jan  9 11:51:54 2014
@@ -0,0 +1,182 @@
+#include <stdio.h>
+
+#include "j3/j3.h"
+#include "j3/j3thread.h"
+#include "j3/j3reader.h"
+#include "j3/j3codegen.h"
+#include "j3/j3class.h"
+#include "j3/j3constants.h"
+#include "j3/j3classloader.h"
+#include "j3/j3method.h"
+#include "j3/j3mangler.h"
+#include "j3/j3jni.h"
+#include "j3/j3object.h"
+#include "j3/j3field.h"
+#include "j3/j3attribute.h"
+#include "j3/j3utf16.h"
+
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Argument.h"
+#include "llvm/IR/Intrinsics.h"
+
+#include "llvm/DebugInfo.h"
+#include "llvm/DIBuilder.h"
+
+#define DEBUG_TYPE_INT    0
+#define DEBUG_TYPE_FLOAT  1
+#define DEBUG_TYPE_OBJECT 2
+
+using namespace j3;
+
+void J3CodeGen::echoDebugEnter(uint32_t isLeave, const char* msg, ...) {
+	static __thread uint32_t prof = 0;
+	if(J3Thread::get()->vm()->options()->debugExecute >= 1) {
+		const char* enter = isLeave ? "leaving" : "entering";
+		va_list va;
+		va_start(va, msg);
+
+		if(!isLeave)
+			prof += J3Thread::get()->vm()->options()->debugEnterIndent;
+		fprintf(stderr, "%*s", prof, "");
+		if(isLeave)
+			prof -= J3Thread::get()->vm()->options()->debugEnterIndent;
+		
+		fprintf(stderr, "%s ", enter);
+		vfprintf(stderr, msg, va);
+		va_end(va);
+	}
+}
+
+void J3CodeGen::echoDebugExecute(uint32_t level, const char* msg, ...) {
+	if(J3Thread::get()->vm()->options()->debugExecute >= level) {
+		va_list va;
+		va_start(va, msg);
+		vfprintf(stderr, msg, va);
+		va_end(va);
+	}
+}
+
+void J3CodeGen::echoElement(uint32_t level, uint32_t type, uintptr_t elmt) {
+	if(J3Thread::get()->vm()->options()->debugExecute >= level) {
+		switch(type) {
+			case DEBUG_TYPE_INT:    
+				fprintf(stderr, "%lld", (uint64_t)elmt); 
+				break;
+
+			case DEBUG_TYPE_FLOAT:  
+				fprintf(stderr, "%lf", *((double*)&elmt)); 
+				break;
+
+			case DEBUG_TYPE_OBJECT: 
+				if(elmt) {
+					J3Object* pobj = (J3Object*)elmt;
+					J3* vm = J3Thread::get()->vm();
+					J3ObjectHandle* prev = J3Thread::get()->tell();
+					J3ObjectHandle* content = 0;
+					
+					if(pobj->vt()->type() == vm->typeCharacter->getArray())
+						content = J3Thread::get()->push(pobj);
+					else if(pobj->vt()->type() == vm->stringClass) {
+						J3ObjectHandle* str = J3Thread::get()->push(pobj);
+						content = str->getObject(vm->stringClassValue);
+					}
+
+					if(content) {
+						char buf[J3Utf16Decoder::maxSize(content)];
+						J3Utf16Decoder::decode(content, buf);
+						J3Thread::get()->restore(prev);
+						fprintf(stderr, "%s [%s]", pobj->vt()->type()->name()->cStr(), buf);
+					} else
+						fprintf(stderr, "%s@%p", pobj->vt()->type()->name()->cStr(), (void*)elmt);
+				} else
+					fprintf(stderr, "null");
+				break;
+		}
+	}
+}
+
+void J3CodeGen::genEchoElement(const char* msg, uint32_t idx, llvm::Value* val) {
+	llvm::Type* t = val->getType();
+	builder->CreateCall3(funcEchoDebugExecute,
+											 builder->getInt32(4),
+											 buildString(msg),
+											 builder->getInt32(idx));
+
+	if(t->isIntegerTy())
+		builder->CreateCall3(funcEchoElement, 
+												 builder->getInt32(4),
+												 builder->getInt32(DEBUG_TYPE_INT),
+												 builder->CreateSExtOrBitCast(val, uintPtrTy));
+	else if(t->isPointerTy())
+		builder->CreateCall3(funcEchoElement, 
+												 builder->getInt32(4),
+												 builder->getInt32(DEBUG_TYPE_OBJECT),
+												 builder->CreatePtrToInt(val, uintPtrTy));
+	builder->CreateCall2(funcEchoDebugExecute,
+											 builder->getInt32(4),
+											 buildString("\n"));
+}
+
+void J3CodeGen::genDebugOpcode() {
+	if(vm->options()->genDebugExecute) {
+		llvm::BasicBlock* debug = newBB("debug");
+		llvm::BasicBlock* after = newBB("after");
+		builder
+			->CreateCondBr(builder
+										 ->CreateICmpSGT(builder->CreateLoad(builder
+																												 ->CreateIntToPtr(llvm::ConstantInt::get(uintPtrTy, 
+																																																 (uintptr_t)&vm->options()->debugExecute),
+																																					uintPtrTy->getPointerTo())),
+																		 llvm::ConstantInt::get(uintPtrTy, 0)),
+										 debug, after);
+		builder->SetInsertPoint(debug);
+
+		if(vm->options()->genDebugExecute > 1) {
+			for(uint32_t i=0; i<stack.topStack; i++) {
+				genEchoElement("           stack[%d]: ", i, stack.at(i, stack.metaStack[i]));
+			}
+		}
+		
+		char buf[256];
+		snprintf(buf, 256, "    [%4d] executing: %-20s in %s::%s", javaPC, 
+						 J3Cst::opcodeNames[bc], cl->name()->cStr(), method->name()->cStr());
+		builder->CreateCall3(funcEchoDebugExecute,
+												 builder->getInt32(2),
+												 buildString("%s\n"),
+												 buildString(buf));
+
+		builder->CreateBr(after);
+		builder->SetInsertPoint(bb = after);
+	}
+}
+
+void J3CodeGen::genDebugEnterLeave(bool isLeave) {
+	if(vm->options()->genDebugExecute) {
+		if(isLeave) {
+			char buf[256];
+			snprintf(buf, 256, "%s::%s", cl->name()->cStr(), method->name()->cStr());
+			builder->CreateCall3(funcEchoDebugEnter,
+													 builder->getInt32(1),
+													 buildString("%s\n"),
+													 buildString(buf));
+		} else {
+			char buf[256];
+			snprintf(buf, 256, "%s::%s", cl->name()->cStr(), method->name()->cStr());
+			builder->CreateCall3(funcEchoDebugEnter,
+													 builder->getInt32(0),
+													 buildString("%s\n"),
+													 buildString(buf));
+			
+			if(vm->options()->genDebugExecute > 1) {
+				uint32_t i = 0;
+				for(llvm::Function::arg_iterator cur=llvmFunction->arg_begin(); cur!=llvmFunction->arg_end(); cur++) {
+					genEchoElement("           arg[%d]: ", i++, cur);
+				}
+			}
+		}
+	}
+}
+

Modified: vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc?rev=198877&r1=198876&r2=198877&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc Thu Jan  9 11:51:54 2014
@@ -28,11 +28,6 @@ using namespace j3;
 
 #define _onEndPoint() ({ if(onEndPoint()) return; })
 
-#define DEBUG_TYPE_INT    0
-#define DEBUG_TYPE_FLOAT  1
-#define DEBUG_TYPE_OBJECT 2
-
-
 J3CodeGen::J3CodeGen(vmkit::BumpAllocator* _allocator, J3Method* m, bool withMethod, bool withCaller) :
 	exceptions(this) {
 	
@@ -849,52 +844,6 @@ llvm::Value* J3CodeGen::buildString(cons
 	return builder->CreateGEP(var, gep);
 }
 
-void J3CodeGen::echoDebugEnter(uint32_t isLeave, const char* msg, ...) {
-	static __thread uint32_t prof = 0;
-	if(J3Thread::get()->vm()->options()->debugExecute >= 1) {
-		const char* enter = isLeave ? "leaving" : "entering";
-		va_list va;
-		va_start(va, msg);
-
-		if(!isLeave)
-			prof += J3Thread::get()->vm()->options()->debugEnterIndent;
-		fprintf(stderr, "%*s", prof, "");
-		if(isLeave)
-			prof -= J3Thread::get()->vm()->options()->debugEnterIndent;
-		
-		fprintf(stderr, "%s ", enter);
-		vfprintf(stderr, msg, va);
-		va_end(va);
-	}
-}
-
-void J3CodeGen::echoDebugExecute(uint32_t level, const char* msg, ...) {
-	if(J3Thread::get()->vm()->options()->debugExecute >= level) {
-		va_list va;
-		va_start(va, msg);
-		vfprintf(stderr, msg, va);
-		va_end(va);
-	}
-}
-
-void J3CodeGen::echoElement(uint32_t level, uint32_t type, uintptr_t elmt) {
-	if(J3Thread::get()->vm()->options()->debugExecute >= level) {
-		switch(type) {
-			case DEBUG_TYPE_INT:    
-				fprintf(stderr, "%lld", (uint64_t)elmt); 
-				break;
-
-			case DEBUG_TYPE_FLOAT:  
-				fprintf(stderr, "%lf", *((double*)&elmt)); 
-				break;
-
-			case DEBUG_TYPE_OBJECT: 
-				fprintf(stderr, "%p::%s", (void*)elmt, ((J3Object*)elmt)->vt()->type()->name()->cStr());
-				break;
-		}
-	}
-}
-
 void J3CodeGen::translate() {
 	if(vm->options()->debugTranslate > 1)
 		exceptions.dump(vm->options()->debugTranslate-1);
@@ -958,7 +907,7 @@ void J3CodeGen::translate() {
 		else 
 			opInfos[javaPC].insn = bb->end()->getPrevNode();
 
-		uint8_t bc   = codeReader->readU1();
+		bc = codeReader->readU1();
 
 		switch(vm->options()->debugTranslate) {
 			default:
@@ -976,49 +925,7 @@ void J3CodeGen::translate() {
 				break;
 		}
 
-		if(vm->options()->genDebugExecute) {
-			if(vm->options()->genDebugExecute > 1) {
-				llvm::BasicBlock* debug = newBB("debug");
-				llvm::BasicBlock* after = newBB("after");
-				builder
-					->CreateCondBr(builder
-												 ->CreateICmpSGE(builder->CreateLoad(builder
-																														 ->CreateIntToPtr(llvm::ConstantInt::get(uintPtrTy, 
-																																																		 (uintptr_t)&vm->options()->debugExecute),
-																																							uintPtrTy->getPointerTo())),
-																				builder->getInt32(4)),
-												 debug, after);
-				builder->SetInsertPoint(debug);
-				for(uint32_t i=0; i<stack.topStack; i++) {
-					builder->CreateCall3(funcEchoDebugExecute,
-															 builder->getInt32(4),
-															 buildString("           stack[%d]: "),
-															 builder->getInt32(i));
-					if(stack.metaStack[i]->isIntegerTy())
-						builder->CreateCall3(funcEchoElement, 
-																 builder->getInt32(4),
-																 builder->getInt32(DEBUG_TYPE_INT),
-																 builder->CreateSExtOrBitCast(stack.at(i, stack.metaStack[i]), uintPtrTy));
-					else if(stack.metaStack[i]->isPointerTy())
-						builder->CreateCall3(funcEchoElement, 
-																 builder->getInt32(4),
-																 builder->getInt32(DEBUG_TYPE_OBJECT),
-																 builder->CreatePtrToInt(stack.at(i, stack.metaStack[i]), uintPtrTy));
-					builder->CreateCall2(funcEchoDebugExecute,
-															 builder->getInt32(4),
-															 buildString("\n"));
-				}
-				builder->CreateBr(after);
-				builder->SetInsertPoint(bb = after);
-			}
-			char buf[256];
-			snprintf(buf, 256, "    [%4d] executing: %-20s in %s::%s", javaPC, 
-							 J3Cst::opcodeNames[bc], cl->name()->cStr(), method->name()->cStr());
-			builder->CreateCall3(funcEchoDebugExecute,
-													 builder->getInt32(2),
-													 buildString("%s\n"),
-													 buildString(buf));
-		}
+		genDebugOpcode();
 
 		switch(bc) {
 			case J3Cst::BC_nop:                           /* 0x00 */
@@ -1642,7 +1549,7 @@ void J3CodeGen::translate() {
 void J3CodeGen::explore() {
 	printf("  exploring bytecode of: %s::%s%s\n", cl->name()->cStr(), method->name()->cStr(), method->signature()->cStr());
 	while(codeReader->remaining()) {
-		uint8_t bc = codeReader->readU1();
+		bc = codeReader->readU1();
 
 		printf("    exploring: %s (%d)\n", J3Cst::opcodeNames[bc], bc);
 		switch(bc) {
@@ -1699,45 +1606,11 @@ void J3CodeGen::generateJava() {
 	stack.init(this, maxStack, allocator->allocate(J3CodeGenVar::reservedSize(maxStack)));
 	ret.init(this, 1, allocator->allocate(J3CodeGenVar::reservedSize(1)));
 
-
-	if(vm->options()->genDebugExecute) {
-		char buf[256];
-		snprintf(buf, 256, "%s::%s", cl->name()->cStr(), method->name()->cStr());
-#if 0
-
-		fprintf(stderr, "bitcast: ");
-		builder->CreateBitCast(funcEchoDebugEnter, builder->getInt8PtrTy())->dump();
-		fprintf(stderr, "\n");
-
-		llvm::Value* args[] = {
-			builder->getInt64(42),   /* patch point id */
-			builder->getInt32(0),    /* pad */
-			builder->CreateBitCast(funcEchoDebugEnter, builder->getInt8PtrTy()),     /* function funcEchoDebugEnter */
-			builder->getInt32(3),    /* number of args */
-			builder->getInt32(0),    /* arg[0] */
-			buildString("bip %s\n"), /* arg[1] */
-			buildString(buf)         /* arg[2] */
-		};
-		builder->CreateCall(patchPointVoid, args)->dump();
-#else
-		builder->CreateCall3(funcEchoDebugEnter,
-												 builder->getInt32(0),
-												 buildString("%s\n"),
-												 buildString(buf));
-#endif
-	}
+	genDebugEnterLeave(0);
 
 	uint32_t n=0, pos=0;
 	for(llvm::Function::arg_iterator cur=llvmFunction->arg_begin(); cur!=llvmFunction->arg_end(); cur++) {
 		locals.setAt(flatten(cur), pos);
-
-		if(vm->options()->genDebugExecute)
-			builder->CreateCall4(funcEchoDebugExecute,
-													 builder->getInt32(2),
-													 buildString("            arg[%d]: %p\n"),
-													 builder->getInt32(pos),
-													 locals.at(pos, cur->getType()));
-		
 		pos += (cur->getType() == vm->typeLong->llvmType() || cur->getType() == vm->typeDouble->llvmType()) ? 2 : 1;
 	}
 
@@ -1752,14 +1625,8 @@ void J3CodeGen::generateJava() {
 
 	bbRet = newBB("ret");
 	builder->SetInsertPoint(bbRet);
-	if(vm->options()->genDebugExecute) {
-		char buf[256];
-		snprintf(buf, 256, "%s::%s", cl->name()->cStr(), method->name()->cStr());
-		builder->CreateCall3(funcEchoDebugEnter,
-												 builder->getInt32(1),
-												 buildString("%s\n"),
-												 buildString(buf));
-	}
+
+	genDebugEnterLeave(1);
 
 	if(llvmFunction->getReturnType()->isVoidTy())
 		builder->CreateRetVoid();

Modified: vmkit/branches/mcjit/lib/j3/vm/j3utf16.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3utf16.cc?rev=198877&r1=198876&r2=198877&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3utf16.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3utf16.cc Thu Jan  9 11:51:54 2014
@@ -23,7 +23,7 @@ uint16_t J3Utf16Encoder::nextUtf16() {
 	if(x & 0x80) {
 		uint16_t y = str[pos++];
 		if (x & 0x20) {
-			char z = str[pos++];
+			uint16_t z = str[pos++];
 			x = ((x & 0x0F) << 12) +
 				((y & 0x3F) << 6) +
 				(z & 0x3F);
@@ -42,10 +42,15 @@ size_t J3Utf16Decoder::decode(J3ObjectHa
 
 	for(uint32_t i=0; i<length; i++) {
 		uint16_t c = charArray->getCharacterAt(i);
-		if(c > 127) {
-			J3::internalError("implement me: fun char");
-		} else {
+		if(c < (1<<7)) {
 			dest[pos++] = (char)c;
+		} else if(c < (1<<11)) {
+			dest[pos++] = ((c>>6) & 0x1f) | 0x80;
+			dest[pos++] = c & 0x3f;
+		} else {
+			dest[pos++] = ((c>>12) & 0xf) | (0x80 + 0x20);
+			dest[pos++] = (c>>6) & 0x3f;
+			dest[pos++] = c & 0x3f;
 		}
 	}
 





More information about the vmkit-commits mailing list