Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feature/32/fast_block_return' in…
Browse files Browse the repository at this point in the history
…to develop

* origin/feature/32/fast_block_return:
  Fixes constness and indentation in MethodCompiler and soft VM
  Adds logic to support MRV ABI
  Implements call propagation method of block return
  Removes usage of Opts.JITExceptionHandling
  Uses llvm-3.4

Issue: #32
  • Loading branch information
0x7CFE committed Jun 18, 2016
2 parents 97ce220 + a134dc1 commit 5f6a502
Show file tree
Hide file tree
Showing 11 changed files with 485 additions and 219 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ addons:
- g++-multilib
- linux-libc-dev:i386
- libreadline-dev:i386
- llvm-3.3-dev:i386
- llvm-3.4-dev:i386

notifications:
email: false
Expand Down
2 changes: 1 addition & 1 deletion .travis/osx/before_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ function brew_upgrade { brew outdated $1 || brew upgrade $1; }

brew update
brew install readline
brew install llvm33
brew install llvm34
7 changes: 5 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.4)

set (CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_SOURCE_DIR}/cmake/variables.cmake")
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set (LLVM_PACKAGE_VERSION 3.3)
set (LLVM_PACKAGE_VERSION 3.4)

project(llst)

Expand Down Expand Up @@ -127,13 +127,16 @@ if (USE_LLVM)
src/llstPass.cpp
src/llstDebuggingPass.cpp
)

add_library(trampoline "src/trampoline.cpp")
set_source_files_properties(src/trampoline.cpp PROPERTIES COMPILE_FLAGS "-freg-struct-return")
endif()

add_executable(llst src/main.cpp)
add_dependencies(llst image)

if (USE_LLVM)
target_link_libraries(llst jit ${LLVM_LIBS} ${LLVM_LD_FLAGS})
target_link_libraries(llst jit trampoline ${LLVM_LIBS} ${LLVM_LD_FLAGS})
endif()
target_link_libraries(llst standard_set memory_managers stapi ${READLINE_LIBS_TO_LINK} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})

Expand Down
5 changes: 4 additions & 1 deletion image/imageSource.st
Original file line number Diff line number Diff line change
Expand Up @@ -1996,7 +1996,7 @@ run2: rounds | mock |
self run: [ mock selfSend ] rounds: rounds text: 'Self dispatch'.

self run: [ mock invokeBlock: [nil] ] rounds: rounds text: 'Block invoke'.
self run: [ mock blockReturn ] rounds: rounds text: 'Block return'.
self run: [ 1 to: rounds do: [ :x | mock blockReturn ] ] rounds: 1 text: 'Block return'.

self run: [ mock selfReturn selfReturn selfReturn selfReturn selfReturn ] rounds: rounds text: 'Chain dispatch'.
self run: [ mock selfReturn; selfReturn; selfReturn; selfReturn; selfReturn ] rounds: rounds text: 'Cascade dispatch'.
Expand Down Expand Up @@ -2061,6 +2061,9 @@ main | command data x |
Class fillChildren.
System fixMethodClasses.

"Jit do: [ nil runAllTests ].
Jit do: [ System rebuildImage ]."

[ command <- String readline: '->'. command notNil ]
whileTrue: [ command isEmpty ifFalse: [ command doIt printNl ] ]

Expand Down
35 changes: 33 additions & 2 deletions include/Core.ll
Original file line number Diff line number Diff line change
Expand Up @@ -333,20 +333,51 @@ declare %TByteObject* @newBinaryObject(%TClass*, i32)
;;;;;;;;;;;;;;;;; runtime API ;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

declare %TObject* @sendMessage(%TContext* %callingContext, %TSymbol* %selector, %TObjectArray* %arguments, %TClass* %receiverClass, i32 %callSiteOffset)
;declare %TObject* @sendMessage(%TContext* %callingContext, %TSymbol* %selector, %TObjectArray* %arguments, %TClass* %receiverClass, i32 %callSiteOffset)
declare { %TObject*, %TContext* } @sendMessage(%TContext* %callingContext, %TSymbol* %selector, %TObjectArray* %arguments, %TClass* %receiverClass, i32 %callSiteOffset)

declare %TBlock* @createBlock(%TContext* %callingContext, i8 %argLocation, i16 %bytePointer)
declare %TObject* @invokeBlock(%TBlock* %block, %TContext* %callingContext)
declare { %TObject*, %TContext* } @invokeBlock(%TBlock* %block, %TContext* %callingContext)
;declare %TObject* @invokeBlock(%TBlock* %block, %TContext* %callingContext)

declare void @emitBlockReturn(%TObject* %value, %TContext* %targetContext)
declare void @checkRoot(%TObject* %value, %TObject** %slot)
declare i1 @bulkReplace(%TObject* %destination, %TObject* %sourceStartOffset, %TObject* %source, %TObject* %destinationStopOffset, %TObject* %destinationStartOffset)
declare %TObject* @callPrimitive(i8 %opcode, %TObjectArray* %args, i1* %primitiveFailed)

%TReturnValue = type {
%TObject*, ; value
%TContext* ; targetContext
}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;; exception API ;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

declare i32 @__gcc_personality_v0(...)
declare i32 @__gxx_personality_v0(...)
declare i8* @__cxa_begin_catch(i8*)
declare void @__cxa_end_catch()
declare i8* @__cxa_allocate_exception(i32)
declare void @__cxa_throw(i8*, i8*, i8*)


define { i32, i32 } @"test2"(%TContext* %contextParameter) #1 {
%1 = insertvalue { i32, i32 } undef, i32 1, 0
%2 = insertvalue { i32, i32 } %1, i32 2, 1
ret { i32, i32 } %2
}

; Function Attrs: inlinehint
define { %TObject*, %TContext* } @"Mock>>selfReturn_"(%TContext* %pContext) #1 {
preamble:
%0 = getelementptr inbounds %TContext* %pContext, i32 0, i32 2
%1 = load %TObjectArray** %0
%2 = getelementptr inbounds %TObjectArray* %1, i32 0, i32 0
%fields.i.i = getelementptr inbounds %TObject* %2, i32 0, i32 2
%fieldPtr.i.i = getelementptr inbounds [0 x %TObject*]* %fields.i.i, i32 0, i32 0
%result.i = load %TObject** %fieldPtr.i.i
%3 = insertvalue { %TObject*, %TContext* } undef, %TObject* %result.i, 0
%4 = insertvalue { %TObject*, %TContext* } %3, %TContext* null, 1
ret { %TObject*, %TContext* } %4
}
61 changes: 42 additions & 19 deletions include/jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ struct TObjectTypes {
llvm::StructType* byteObject;
llvm::StructType* blockReturn;
llvm::StructType* process;

llvm::StructType* returnValueType;

void initializeFromModule(llvm::Module* module) {
object = module->getTypeByName("TObject");
Expand All @@ -106,6 +106,12 @@ struct TObjectTypes {
byteObject = module->getTypeByName("TByteObject");
blockReturn = module->getTypeByName("TBlockReturn");
process = module->getTypeByName("TProcess");

returnValueType = llvm::StructType::get(
object->getPointerTo(),
context->getPointerTo(),
NULL
);
}
};

Expand Down Expand Up @@ -206,6 +212,9 @@ class MethodCompiler {

llvm::BasicBlock* preamble;
llvm::BasicBlock* exceptionLandingPad;
llvm::BasicBlock* unwindBlockReturn;
llvm::PHINode* unwindPhi;

bool methodHasBlockReturn;
bool methodAllocatesMemory;

Expand All @@ -221,7 +230,7 @@ class MethodCompiler {

TJITContext(MethodCompiler* compiler, TMethod* method, bool parse = true)
: currentNode(0), originMethod(method), function(0), builder(0),
preamble(0), exceptionLandingPad(0), methodHasBlockReturn(false),
preamble(0), exceptionLandingPad(0), unwindBlockReturn(0), unwindPhi(0), methodHasBlockReturn(false),
methodAllocatesMemory(true), compiler(compiler), contextHolder(0), selfHolder(0)
{
if (parse) {
Expand Down Expand Up @@ -289,6 +298,8 @@ class MethodCompiler {
void writeFunctionBody(TJITContext& jit);
void writeInstruction(TJITContext& jit);
void writeLandingPad(TJITContext& jit);
void writeUnwindBlockReturn(TJITContext& jit);
void emitReturn(TJITContext& jit, llvm::Value* object, llvm::Value* targetContext = 0);

void doPushInstance(TJITContext& jit);
void doPushArgument(TJITContext& jit);
Expand Down Expand Up @@ -370,12 +381,25 @@ class MethodCompiler {
}
};


struct TReturnValue {
TObject* value;
TContext* targetContext;

TReturnValue(TObject* value = 0, TContext* targetContext = 0)
: value(value), targetContext(targetContext) { }

static void* getBlockReturnType() {
return const_cast<void*>(reinterpret_cast<const void*>( &typeid(TReturnValue) ));
}
};

extern "C" {
TObject* newOrdinaryObject(TClass* klass, uint32_t slotSize);
TByteObject* newBinaryObject(TClass* klass, uint32_t dataSize);
TObject* sendMessage(TContext* callingContext, TSymbol* message, TObjectArray* arguments, TClass* receiverClass, uint32_t callSiteIndex);
TReturnValue sendMessage(TContext* callingContext, TSymbol* message, TObjectArray* arguments, TClass* receiverClass, uint32_t callSiteIndex);
TBlock* createBlock(TContext* callingContext, uint8_t argLocation, uint16_t bytePointer);
TObject* invokeBlock(TBlock* block, TContext* callingContext);
TReturnValue invokeBlock(TBlock* block, TContext* callingContext);
void emitBlockReturn(TObject* value, TContext* targetContext);
const void* getBlockReturnType();
void checkRoot(TObject* value, TObject** objectSlot);
Expand All @@ -389,10 +413,12 @@ extern "C" {

class JITRuntime {
public:
typedef TObject* (*TMethodFunction)(TContext*);
typedef TObject* (*TBlockFunction)(TBlock*);
typedef TReturnValue (*TMethodFunction)(TContext*);
typedef TReturnValue (*TBlockFunction)(TBlock*);

private:
friend class SmalltalkVM;

llvm::FunctionPassManager* m_functionPassManager;
llvm::PassManager* m_modulePassManager;

Expand All @@ -408,15 +434,16 @@ class JITRuntime {

static JITRuntime* s_instance;

TObject* sendMessage(TContext* callingContext, TSymbol* message, TObjectArray* arguments, TClass* receiverClass, uint32_t callSiteIndex = 0);
void sendMessage(TContext* callingContext, TSymbol* message, TObjectArray* arguments, TClass* receiverClass, uint32_t callSiteIndex, TReturnValue& result);
void invokeBlock(TBlock* block, TContext* callingContext, TReturnValue& result);

TBlock* createBlock(TContext* callingContext, uint8_t argLocation, uint16_t bytePointer);

friend TObject* newOrdinaryObject(TClass* klass, uint32_t slotSize);
friend TByteObject* newBinaryObject(TClass* klass, uint32_t dataSize);
friend TObject* sendMessage(TContext* callingContext, TSymbol* message, TObjectArray* arguments, TClass* receiverClass, uint32_t callSiteIndex);
friend TReturnValue sendMessage(TContext* callingContext, TSymbol* message, TObjectArray* arguments, TClass* receiverClass, uint32_t callSiteIndex);
friend TBlock* createBlock(TContext* callingContext, uint8_t argLocation, uint16_t bytePointer);
friend TObject* invokeBlock(TBlock* block, TContext* callingContext);
friend TReturnValue invokeBlock(TBlock* block, TContext* callingContext);
friend void emitBlockReturn(TObject* value, TContext* targetContext);

struct TFunctionCacheEntry
Expand Down Expand Up @@ -511,7 +538,7 @@ class JITRuntime {
bool detectLiteralReceiver(llvm::Value* messageArguments);
public:

TObject* invokeBlock(TBlock* block, TContext* callingContext, bool once = false);
void invokeBlock(TBlock* block, TContext* callingContext, TReturnValue& result, bool once = false);

void patchHotMethods();
void printMethod(TMethod* method) {
Expand All @@ -537,13 +564,9 @@ class JITRuntime {
~JITRuntime();
};

struct TBlockReturn {
TObject* value;
TContext* targetContext;
TBlockReturn(TObject* value, TContext* targetContext)
: value(value), targetContext(targetContext) { }
extern "C" {

static void* getBlockReturnType() {
return const_cast<void*>(reinterpret_cast<const void*>( &typeid(TBlockReturn) ));
}
};
void methodTrampoline(JITRuntime::TMethodFunction function, TContext* context, TReturnValue& result);
void blockTrampoline(JITRuntime::TBlockFunction function, TBlock* block, TReturnValue& result);

}
Loading

0 comments on commit 5f6a502

Please sign in to comment.