diff --git a/scripting/abc.cpp b/scripting/abc.cpp index 4a7d9d53c3..0beda4c8dd 100644 --- a/scripting/abc.cpp +++ b/scripting/abc.cpp @@ -2055,7 +2055,7 @@ ASObject* method_info::getOptional(unsigned int i) const BlockStudy* method_info::mergeBlocks(uint32_t aggregateStart, uint32_t aggregateEnd) { auto itStart=lower_bound(studiedBlocks.begin(),studiedBlocks.end(),aggregateStart); - auto itEnd=lower_bound(studiedBlocks.begin(),studiedBlocks.end(),aggregateEnd-1)-1; + auto itEnd=upper_bound(studiedBlocks.begin(),studiedBlocks.end(),aggregateEnd-1)-1; assert(itStart!=studiedBlocks.end()); assert(itStart->start<=aggregateStart && itStart->end>aggregateStart); assert(itEnd->start<=aggregateEnd && itEnd->end>=aggregateEnd); @@ -2085,7 +2085,7 @@ BlockStudy* method_info::getBlockStudyAtAddress(uint32_t ip, CREATE_STUDY_BLOCK if(createBlock==CREATE) { it->usageCount++; - if(it->compiledCode==NULL && it->usageCount>usageCountThreshold) + if(it->blockType==BlockStudy::JIT_CANDIDATE && it->usageCount>usageCountThreshold) { //This block is a candidate for compilation uint32_t aggregateStart=it->start; @@ -2130,6 +2130,7 @@ BlockStudy* method_info::getBlockStudyAtAddress(uint32_t ip, CREATE_STUDY_BLOCK if(it->start!=aggregateStart || it->end!=aggregateEnd) b=mergeBlocks(aggregateStart, aggregateEnd); b->compiledCode=compileBlock(b->start,b->end); + b->blockType=(b->compiledCode)?(BlockStudy::JIT_OK):(BlockStudy::JIT_FAILED); } } return b; @@ -2139,29 +2140,6 @@ BlockStudy* method_info::getBlockStudyAtAddress(uint32_t ip, CREATE_STUDY_BLOCK return NULL; afterIt=studiedBlocks.insert(afterIt, BlockStudy(ip)); return &(*afterIt); - -/* //TODO: optimize the search - for(uint32_t i=0;iusageCountThreshold) - { - studiedBlocks[i].compiledCode=compileBlock(studiedBlocks[i].start,studiedBlocks[i].end); - } - } - return &studiedBlocks[i]; - } - } - if(createBlock==DO_NOT_CREATE) - return NULL; - studiedBlocks.emplace_back(ip); - return &studiedBlocks.back();*/ } istream& lightspark::operator>>(istream& in, u32& v) diff --git a/scripting/abc.h b/scripting/abc.h index 833f4dea7a..bf3d49596c 100644 --- a/scripting/abc.h +++ b/scripting/abc.h @@ -221,12 +221,16 @@ inline stack_entry make_stack_entry(llvm::Value* v, STACK_TYPE t) struct BlockStudy { //start is the first address inside the block + uint32_t start; //end is the first byte _not_ inside the block - uint32_t start,end; + uint32_t end; uint32_t usageCount; + + enum BLOCK_TYPE { JIT_CANDIDATE=0, JIT_OK, JIT_FAILED }; + BLOCK_TYPE blockType; typedef intptr_t (*synt_block)(call_context* cc); synt_block compiledCode; - BlockStudy(uint32_t a):start(a),end(a+1),usageCount(1),compiledCode(NULL) + BlockStudy(uint32_t a):start(a),end(a+1),usageCount(1),blockType(JIT_CANDIDATE),compiledCode(NULL) { } bool isAddressInside(uint32_t ip) const diff --git a/scripting/abc_codesynt.cpp b/scripting/abc_codesynt.cpp index e71faa1e59..034d9204dc 100644 --- a/scripting/abc_codesynt.cpp +++ b/scripting/abc_codesynt.cpp @@ -2383,6 +2383,8 @@ BlockStudy::synt_block method_info::compileBlock(uint32_t start, uint32_t end) default: LOG(LOG_ERROR,_("Not implemented instruction @") << code.tellg()); LOG(LOG_ERROR,_("Opcode ") << hex << (unsigned int)opcode << dec); + llvmf->eraseFromParent(); + cout << "Failed to compile " << profName << endl; return NULL; /*constant = llvm::ConstantInt::get(int_type, opcode); Builder.CreateCall(ex->FindFunctionNamed("not_impl"), constant); @@ -2464,8 +2466,7 @@ BlockStudy::synt_block method_info::compileBlock(uint32_t start, uint32_t end) } } - //__asm__("int $3"); - cout << "start: " << start << " end: " << end << endl; + //cout << profName << " start: " << start << " end: " << end << endl; //llvmf->dump(); getVm()->FPM->run(*llvmf); BlockStudy::synt_block ret=(BlockStudy::synt_block)getVm()->ex->getPointerToFunction(llvmf); diff --git a/scripting/abc_interpreter.cpp b/scripting/abc_interpreter.cpp index cfdc68d066..d753fcc12c 100644 --- a/scripting/abc_interpreter.cpp +++ b/scripting/abc_interpreter.cpp @@ -73,7 +73,7 @@ ASObject* ABCVm::executeFunction(SyntheticFunction* function, call_context* cont if(mi->studyFunction) { BlockStudy* nextBlock=mi->getBlockStudyAtAddress(instructionPointer, method_info::DO_NOT_CREATE); - if(nextBlock && nextBlock->compiledCode && nextBlock->start==instructionPointer) + if(nextBlock && nextBlock->blockType==BlockStudy::JIT_OK && nextBlock->start==instructionPointer) { //Call JItted code mi->checkJITAssumptions(context); diff --git a/scripting/toplevel.cpp b/scripting/toplevel.cpp index 754dc3f916..01b6ea938c 100644 --- a/scripting/toplevel.cpp +++ b/scripting/toplevel.cpp @@ -2244,8 +2244,8 @@ ASObject* SyntheticFunction::call(ASObject* obj, ASObject* const* args, uint32_t return NULL; } - if(mi->profName=="BigInteger::http://crypto.hurlant.com/BigInteger::am" && mi->studyFunction==false) -// if(hit_count==hit_threshold) +// if(mi->profName=="BigInteger::http://crypto.hurlant.com/BigInteger::am" && mi->studyFunction==false) + if(hit_count==hit_threshold) { cout << "Studying " << mi->profName << endl; mi->studyFunction=true;