How to precompile SpiderMonkey code for faster execution? - spidermonkey

I am using code like this:
JS_EvaluateScript(context, global,"go_back('blabla')", 17, "", 1, &R);
to call go_back(), which is already in the context. But this is extremely slow, and I think because the string have to be compiled each time.
I try to find the way to call the same piece of code many times in a fast way, without recompilation, or some object creation each time. But Mozilla docs and sources are not organized that way, there is only a reference, and you need to know every function before you can make any choice.
So any hints? What would be the best practice for this?

JSFunction * FUNC = 0;
static JSBool my_native(JSContext *cx, uintN argc, jsval *vp) {
jsval R = JSVAL_FALSE;
if (FUNC == 0) {
const char *ARGS[1] = {"s"}, *src = "go_back(s)";
FUNC = JS_CompileFunction(cx, 0, 0, 1, ARGS, src, 10, "", 0);
}
JS_CallFunction(cx, 0, FUNC, 1, &R, &R);
return JS_TRUE;
}
This is very fast (20 times in my example), compared to JS_EvaluateScript. Note that this code is very simplified, you still need to pass the string argument somehow. (I am not sure myself how to do that.) And you may need to JS_ReportPendingException() as go_back() can sometimes fail.

Related

Need help using promise and future for the first time in C++ 14

i'm currently coding a chess game which includes a chess IA to play with. My chess IA working fine with minimax and alpha beta optimisation. But now, I would like to make it faster by using multithreading. It's my first time of using thread so I started first by running the minimax function on a single separate thread to test it out.
This is my code :
`
std::function<std::pair<Move*, float>(Board, int, float, float, bool , bool)> task;
task = [&task](Board &board, int depth, float alpha, float beta, bool maximizingPlayer, bool maximizingColor) ->std::pair<Move*, float>
{
if (depth == 0 || board.GameIsOver())
return std::make_pair(nullptr, evaluate(board, maximizingColor));
auto possibleMoves = board.AllMovePossible(maximizingPlayer);
Move bestMove;
if (maximizingPlayer) {
float maxEval = INFINITY;
for (PossibleMoves& p : possibleMoves) {
for (auto& move : p.moves) {
board.Move(p.piece, move.first, move.second);
int currentEval = task(board, depth - 1, alpha, beta, false, maximizingColor).second;
board.UndoMove();
if (currentEval < maxEval) {
maxEval = currentEval;
bestMove = Move(p.piece, move);
}
beta = min(beta, currentEval);
if (beta <= alpha)
break;
}
}
return std::make_pair(&bestMove, maxEval);
}
else {
float maxEval = -INFINITY;
for (PossibleMoves& p : possibleMoves) {
for (auto& move : p.moves) {
board.Move(p.piece, move.first, move.second);
int currentEval = task(board, depth - 1, alpha, beta, true, maximizingColor).second;
board.UndoMove();
if (currentEval > maxEval) {
maxEval = currentEval;
bestMove = Move(p.piece, move);
}
alpha = max(alpha, currentEval);
if (beta <= alpha)
break;
}
}
return std::make_pair(&bestMove, maxEval);
}};
std::function<void(std::promise<std::pair<Move*, float>>, Board, int, float, float, bool, bool)> taskWorker;
taskWorker = [&task](std::promise<std::pair<Move*, float>> &&p, Board board, int depth, float alpha, float beta, bool maximizingPlayer, bool maximizingColor)
{std::pair<Move*, int> bestMove = task(board, depth, alpha, beta, maximizingPlayer, maximizingColor);
p.set_value(bestMove);
};
std::promise<std::pair<Move*, float>> p;
auto f = p.get_future();
std::thread worker(taskWorker,std::move(p),board,depth, alpha, beta, maximizingPlayer, maximizingColor);
std::pair<Move*, int> bestMoveFromThread = f.get();
worker.join();
return bestMoveFromThread;`
To explain my code: the lambda function task is my minimax function, it is using recursion and returning the best move for a board past by reference.
Then the taskWorker is what the thread is going to do. It takes a promise in parameter to store the future best move and use the task function to find it. It also takes a copy of the board because i would like to have multiple thread later that doesn't play moves on the same board.
Then I set up my promise p and my future f and I launch the thread with the function taskWorker
then wait for it to end to get the result store in future. But my problem is that f.get() doesn't have result.
Although the thread seems to work fine because when i debug it seems to find the best move and p.set-value(bestMove) change p to 'has-result' with the correct best move stored (screenshots of debugging linked).
So the problem seems to be between std::promise<std::pair<Move*, float>> p; and std::pair<Move*, int> bestMoveFromThread = f.get();
It's my first time using promise and future, so I simply copied examples I found on the internet.
Did I misunderstand something about promise and future ?
Am I not using these correctly ?
Thanks for your answers. (sorry if that came out wrong, I am not native english speaker).
(debugging) promise in the thread
(debugging) promise out of the thread
You're returning a pointer to a local variable (Move* from the task). So there's already big potential for unexpected issues. Also, in some places your pair contains an int, in others a float. That type confusing might explain the rest.
Generally you understand future/promise I think. But for this example you should look into std::async to replace the thread object.

Resolving code analysis warnings with the BOLDDAY macro (used with CMonthCalCtrl)

I have some issues with the CMonthCalCtrl control and modernizing my code. The first problem is related to the BOLDDAY macro.
This macro is used to adjust day states (making specific dates bold on the calendar) and the concept is described in detail here. As documented, you need to define a macro:
#define BOLDDAY(ds, iDay) if(iDay > 0 && iDay < 32) \
(ds) |= (0x00000001 << (iDay-1))
Here is my code that uses this macro so that you have some context:
void CMeetingScheduleAssistantDlg::InitDayStateArray(int iMonthCount, LPMONTHDAYSTATE pDayState, COleDateTime datStart)
{
int iMonth = 0;
COleDateTimeSpan spnDay;
CString strKey;
SPECIAL_EVENT_S *psEvent = nullptr;
if (pDayState == nullptr)
return;
memset(pDayState, 0, sizeof(MONTHDAYSTATE)*iMonthCount);
if (m_pMapSPtrEvents == nullptr && m_Reminders.Count() == 0)
{
return;
}
spnDay.SetDateTimeSpan(1, 0, 0, 0);
auto datDay = datStart;
const auto iStartMonth = datStart.GetMonth();
auto iThisMonth = iStartMonth;
auto iLastMonth = iThisMonth;
do
{
strKey = datDay.Format(_T("%Y-%m-%d"));
if (m_pMapSPtrEvents != nullptr)
{
psEvent = nullptr;
m_pMapSPtrEvents->Lookup(strKey, reinterpret_cast<void*&>(psEvent));
if (psEvent != nullptr)
{
BOLDDAY(pDayState[iMonth], datDay.GetDay());
}
}
if (m_Reminders.HasReminder(datDay))
{
BOLDDAY(pDayState[iMonth], datDay.GetDay());
}
datDay = datDay + spnDay;
iThisMonth = datDay.GetMonth();
if (iThisMonth != iLastMonth)
{
iLastMonth = iThisMonth;
iMonth++;
}
} while (iMonth < iMonthCount);
}
Everywhere I use this BOLDDAY macro I get a code analysis warning (C26481):
warning C26481: Don't use pointer arithmetic. Use span instead (bounds.1).
It is not clear to me if the problem is with the BOLDDAY macro or my own code?
Update
I still get the warning when I turn the macro into a function:
Update 2
If it helps, I currently call the InitDayStateArray function in the following ways:
Method 1:
void CMeetingScheduleAssistantDlg::SetDayStates(CMonthCalCtrl &rCalendar)
{
COleDateTime datFrom, datUntil;
const auto iMonthCount = rCalendar.GetMonthRange(datFrom, datUntil, GMR_DAYSTATE);
auto pDayState = new MONTHDAYSTATE[iMonthCount];
if (pDayState != nullptr)
{
InitDayStateArray(iMonthCount, pDayState, datFrom);
VERIFY(rCalendar.SetDayState(iMonthCount, pDayState));
delete[] pDayState;
}
}
Method 2
void CMeetingScheduleAssistantDlg::OnGetDayStateEnd(NMHDR* pNMHDR, LRESULT* pResult)
{
NMDAYSTATE* pDayState = reinterpret_cast<NMDAYSTATE*>(pNMHDR);
MONTHDAYSTATE mdState[3]{}; // 1 = prev 2 = curr 3 = next
const COleDateTime datStart(pDayState->stStart);
if (pDayState != nullptr)
{
InitDayStateArray(pDayState->cDayState, &mdState[0], datStart);
pDayState->prgDayState = &mdState[0];
}
if (pResult != nullptr)
*pResult = 0;
}
Perhaps if the container for the LPMONTHDAYSTATE information is tweaked somehow it would contribute to resolve this span issue?
Sample code provided by Microsoft used to be published as code that compiles both with a C and C++ compiler. That limits availability of language features, frequently producing code that particularly C++ clients shouldn't be using verbatim.
The case here being the BOLDDAY function-like macro, that's working around not having reference types in C. C++, on the other hand, does, and the macro can be replaced with a function instead:
void bold_day(DWORD& day_state, int const day) noexcept {
if (day > 0 && day < 32) {
day_state |= (0x00000001 << (day - 1));
}
}
Using this function in place of the BOLDDAY macro silences the C26481 diagnostic.
While that works, I'm at a complete loss to understand where the compiler is seeing pointer arithmetic in the macro version. Regardless, replacing a function-like macro with an actual function (or function template) where possible is always desirable.
Update
Things are starting to make sense now. While replacing the function-like macro with a function, as suggested above, is desirable, it will not resolve the issue. My test happened to have used pDayState[0] which still raises C26481 for the macro, but not for the function. Using pDayState[1] instead, the diagnostic is raised in either case.
Let's put the pieces of the puzzle together: Recall that the array subscript expression p[N] is exactly identical to the expression *(p + N) when p is a pointer type and N an integral type. That explains why the compiler is complaining about "pointer arithmetic" when it sees pDayState[iMonth].
Solving that is fairly straight forward. As suggested by the diagnostic, use a std::span (requires C++20). The following changes to InitDayStateArray() make the C26481 diagnostic go away:
void CMeetingScheduleAssistantDlg::InitDayStateArray(int iMonthCount,
LPMONTHDAYSTATE pDayState,
COleDateTime datStart)
{
std::span const day_month_state(pDayState, iMonthCount);
// ...
// memset(pDayState, 0, sizeof(MONTHDAYSTATE)*iMonthCount);
std::fill(begin(day_month_state), end(day_month_state), 0);
// ...
do
{
// ...
{
bold_day(day_month_state[iMonth], datDay.GetDay());
}
}
if (m_Reminders.HasReminder(datDay))
{
bold_day(day_month_state[iMonth], datDay.GetDay());
}
// ...
} while (iMonth < day_month_state.size());
}
A std::span "describes an object that can refer to a contiguous sequence of objects". It takes the decomposed pointer and size arguments that describe an array and reunites them into a single object, recovering the full fidelity of the array.
That sounds great. But remember, this is C++, and there's a caveat: Just like its evil C++17 ancestor std::string_view, a std::span is an unhesitating factory for dangling pointers. You can freely pass them around, and hang on to them far beyond the referenced data being alive. And this is guaranteed for every specialization, starting with C++23.
The other issue is, that addressing this one diagnostic now has several others pop out of nowhere, suggesting that std::span isn't good enough, and gsl::span should be used instead. Addressing those would probably warrant another Q&A altogether.

pthread_create exits the program after finishing function

I try to create program that takes power readings about 10 times in one second and start a new thread every second/minute to update mysql database while the main program continues taking readings. But after I use pthread_create function runs once and then program seems to exit. It is my first time trying to do something with pthread and obviously I am doing something wrong. Please help because it seems smart to use new thread to update mysql, so it will not interrupt main program. I will add my code (bit that are important I think)
the function:
void *showreadout(float readout,int l, int s) {
printf("readout: %f loops: %i sec: %i\n",readout,l,s);
return NULL;
}
and stuff from main:
pthread_t thread;
int p = 0, startminute = currentminute(),startsec,u;
float secreadout;
while (startminute == currentminute()) {
startsec = currentsec();
u = 0;
secreadout = 0;
while (startsec == currentsec()) {
secreadout += doloop(pinnumber);
u++;
}
pthread_create(&thread, NULL, showreadout(secreadout/u,u, startsec), NULL);
p++;
}
The problem was that I was trying to send variables with pthread_create() to my function and it worked once but then things seemed to go "tits up" or rather the program just stopped.
I solved it by making global variable for the readout and updated it after end of each second before calling my function with pthread_create() and using global variable in my function. I dont know is it the right way to approach it but it seems to work.

How to wrap the IO functions in Lua to prevent the user from leaving X directory

How could you wrap the IO functions in Lua to prevent someone from leaving your top level directory.
You place them in "MyDoc" and they have full IO access to everything sub of MyDoc but couldn't for example .. back into the C drive or anywhere else.
open up liolib.c. head over to these 3 functions
static void opencheck (lua_State *L, const char *fname, const char *mode) {
LStream *p = newfile(L);
p->f = fopen(fname, mode);
if (p->f == NULL)
luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno));
}
static int io_open (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
LStream *p = newfile(L);
const char *md = mode; /* to traverse/check mode */
luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode");
p->f = fopen(filename, mode);
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
}
static int io_popen (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
LStream *p = newprefile(L);
p->f = lua_popen(L, filename, mode);
p->closef = &io_pclose;
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
}
these are the functions you want to edit.
the first one receives the file name as the parameter fname, the second and the third
pop it out of the lua stack as the local variable filename.
now all you need to do is
1) get your own process path
2) canonize the given file path
3) compare them so that they are the same up until the last slash on both
4) if they are not the same then in opencheck use luaL_error(L,"access denied to %s", fname);
in the other two return luaL_fileresult(L,0,filename);
Presumably you have sandboxed your user environment, so for instance they can't use the builtin "require" or "dofile" or "setatable"? Basically you have to limit the functions they can call to only what you want, and create your own versions of anything you want to control. There are several ways to do this and they each have their pros and cons and nothing is unbreakable, all you can do is up the bar of experience, effort and time required to break your "jail".
This means you have to work at the C API level, but I would not recommend modifying the source unless you are very familiar with it and can easily determine that your modifications aren't easiy breakable. By staying at the C API level, at least other Lua users can help validate the solidity of the sandbox.
You have to figure out a way to enable your code to call Lua builtin without allowing the user to call the builtin. I believe you can store tables in the lua registry, where only the C code can look. It's been a while. Or maybe if you don't put getmetable in user environment, that allows you to call the builtins via metatable but user can't get to them.
For example, from C
you load the builtins such as io module and save the functions you will wrap (such as open) in a (meta)table table;
delete the builtin table io from _G so user only has access to the version you created; you've saved the functions you will need for later
create a global table called io and set its metatable to what you created in step 1, so it defines only functions you want to give access to, such as a function called "open".
In that function you do whatever filtering you need, before calling the builtin you saved.
The details will make a big difference, and implementation will be different if you use Lua 5.1 vs 5.2, but there are several good articles on sandboxing in Lua on the web (sorry no time to find), take a look and come up with something, then maybe post on Lua user mailing list or SO for pros/cons. ;)

How can I make this prime finder operate in parallel

I know prime finding is well studied, and there are a lot of different implementations. My question is, using the provided method (code sample), how can I go about breaking up the work? The machine it will be running on has 4 quad core hyperthreaded processors and 16GB of ram. I realize that there are some improvements that could be made, particularly in the IsPrime method. I also know that problems will occur once the list has more than int.MaxValue items in it. I don't care about any of those improvements. The only thing I care about is how to break up the work.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Prime
{
class Program
{
static List<ulong> primes = new List<ulong>() { 2 };
static void Main(string[] args)
{
ulong reportValue = 10;
for (ulong possible = 3; possible <= ulong.MaxValue; possible += 2)
{
if (possible > reportValue)
{
Console.WriteLine(String.Format("\nThere are {0} primes less than {1}.", primes.Count, reportValue));
try
{
checked
{
reportValue *= 10;
}
}
catch (OverflowException)
{
reportValue = ulong.MaxValue;
}
}
if (IsPrime(possible))
{
primes.Add(possible);
Console.Write("\r" + possible);
}
}
Console.WriteLine(primes[primes.Count - 1]);
Console.ReadLine();
}
static bool IsPrime(ulong value)
{
foreach (ulong prime in primes)
{
if (value % prime == 0) return false;
if (prime * prime > value) break;
}
return true;
}
}
}
There are 2 basic schemes I see: 1) using all threads to test a single number, which is probably great for higher primes but I cannot really think of how to implement it, or 2) using each thread to test a single possible prime, which can cause a non-continuous string of primes to be found and run into unused resources problems when the next number to be tested is greater than the square of the highest prime found.
To me it feels like both of these situations are challenging only in the early stages of building the list of primes, but I'm not entirely sure. This is being done for a personal exercise in breaking this kind of work.
If you want, you can parallelize both operations: the checking of a prime, and the checking of multiple primes at once. Though I'm not sure this would help. To be honest I'd consider remove the threading in main().
I've tried to stay faithful to your algorithm, but to speed it up a lot I've used x*x instead of reportvalue; this is something you could easily revert if you wish.
To further improve on my core splitting you could determine an algorithm to figure out the number of computations required to perform the divisions based on the size of the numbers and split the list that way. (aka smaller numbers take less time to divide by so make the first partitions larger)
Also my concept of threadpool may not exist the way I want to use it
Here's my go at it(pseudo-ish-code):
List<int> primes = {2};
List<int> nextPrimes = {};
int cores = 4;
main()
{
for (int x = 3; x < MAX; x=x*x){
int localmax = x*x;
for(int y = x; y < localmax; y+=2){
thread{primecheck(y);}
}
"wait for all threads to be executed"
primes.add(nextPrimes);
nextPrimes = {};
}
}
void primecheck(int y)
{
bool primality;
threadpool? pool;
for(int x = 0; x < cores; x++){
pool.add(thread{
if (!smallcheck(x*primes.length/cores,(x+1)*primes.length/cores ,y)){
primality = false;
pool.kill();
}
});
}
"wait for all threads to be executed or killed"
if (primality)
nextPrimes.add(y);
}
bool smallcheck(int a, int b, int y){
foreach (int div in primes[a to b])
if (y%div == 0)
return false;
return true;
}
E: I added what I think pooling should look like, look at revision if you want to see it without.
Use the sieve of Eratosthenes instead. It's not worthwhile to parallelize unless you use a good algorithm in the first place.
Separate the space to sieve into large regions and sieve each in its own thread. Or better use some workqueue concept for large regions.
Use a bit array to represent the prime numbers, it takes less space than representing them explicitly.
See also this answer for a good implementation of a sieve (in Java, no split into regions).

Resources