create blog

go home go home
  1. about
  2. code
  3. wiki
  4. blog

Archive for February, 2009

v8, Application Exit, and Destructors

Friday, February 20th, 2009

While working on a utility that may perhaps evolve into the next version of the Engine, written primarily in JavaScript, I ran into a small problem when I tried to wrap output files for use in JavaScript.

v8, when it “goes away” at program end, does not collect its garbage. Not usually a problem, as most of the time, the operating system will clean up after you. But I didn’t need the memory cleared. I needed a destructor called.

The output file wrapper was wrapping a class which wrapped ostream. The standard library stream usually uses a buffer, and only calling flush() or destroying the stream flushes it to the actual output. I needed this to happen automatically, so I wrote up a simple template class, AutoDestroy, along with a helper function, autoDestroy.

(more…)

Regression Tests

Tuesday, February 17th, 2009

The framework finally became complete enough to where I felt like I could add tests. Perhaps I should have started with tests, but the tests themselves require a composition of many of the components, so it would have been impractical.

Implementing tests had a very nice side-effect. Tests are meant to test expected behavior. As it turns out, there were a lot of areas where the framework did not behave as expected. I fixed at least seven bugs over the course of the two days when I wrote the current four tests. I say “at least” because I often fix bugs as I see them and promptly forget about them, or group them into larger categories when I write the revision release notes.

In short, just by writing a few tests, I drastically increased the system’s stability. And, since they will run often, they will ensure continued stability as well. Short term and long term, testing can be great.

On V8 and Multithreading

Monday, February 2nd, 2009

V8 is not thread-safe. Just look at the code for HandleScopes, located in handles.h:

static v8::ImplementationUtilities::HandleScopeData current_;
const v8::ImplementationUtilities::HandleScopeData previous_;

The way HandleScopes work is simple: each handle is allocated in the current handle scope (HandleScope::current_). When a new HandleScope is created, it sets its previous_ to the previous one, and changes current_ to itself. The current handle scope is stored statically — in short, shared between all threads.

Logic dictates that this would cause problems in multithreading. Big time.

Consider the following overly simplified example:

//thread 1
HandleScope handle_scope;
 
//thread 2
HandleScope handle_scope;
 
//thread 1
Local<Value> test = String::New("test"); //allocated in thread 2's context scope!
 
//thread 2 closes, destroying its handle scope, and thus
//test, which was allocated inside of it
return;
 
//thread 1 continues, and likely crashes, as it tries to use test, which was
//mistakenly allocated inside of thread 2's handle scope (and thread 2's
//handle scope has now ended).
if (test->IsString())
{
 
}

“That’s why that is no work.”

Update: With enough locking, it is possible. v8 even has a Locker object to help. But it is still quite tricky, and appears to be prone to failure. I haven’t tested it much myself, as I currently don’t have a need for threading.

It would still be quite dangerous, especially if one unlocks while inside of a HandleScope.

Interesting Bug #1: The Case of the Sticky Object

Monday, February 2nd, 2009

In my post on persistent handles, I mentioned that it is good to keep a map between native C++ objects and their JavaScript wrappers, so that you can reuse the wrappers.

I also mentioned that I clear V8′s reference to the native object when C++ “forces” a destroy.

Everything worked, except one thing: when I cleared the reference to the native object, I did not clear the reference from the map. Lo and behold, at some later point in time, when such an object is created again, the pointer to the original is still in my map. So, when I ask the map if a wrapper exists, it does. And its reference is NULL. So, I just passed a non-NULL object to JavaScript, and JavaScript got a NULL value.

All I needed to do to fix it was add a std::set of things to alert to the clearing of the reference, add the map-containing object to that set, and call a function which erases the entry in the map-containing object when the reference is cleared.

It is quite lucky for me that this bug occurred. It occurred due to an unintended consequence of normal object destruction. Accidentally, when the object was destroyed even through a process initiated from JavaScript, the “force destruction” message was sent out. Had this unintended side-effect to destruction not been there, I would not have noticed anything, and some wacky consequences of reusing wrappers for unrelated objects could have been extremely difficult to debug.

A bug a day keeps the doctor away?

Apple Postscript Bug

Sunday, February 1st, 2009

Apple’s OS X has a built-in PostScript RIP (actually, it converts to PDF). There is a bug in it that I found awhile back while creating PostScript output for use in PPML: rotating text in increments of 90° fails. Oddly enough, while 90° fails, 89.999° works.

To try this out, open a text editor like TextEdit, and enter the following:

gsave
72 72 translate 
90 rotate 
/Helvetica findfont 24 scalefont setfont 
0 0 moveto 
(Some Postscript Text) show 
grestore

Save it with a .ps extension, and open it using Preview. The text will not be rotated. If you have Adobe Distiller, try that — the text is rotated.

Now change the 90 to 89.999:

gsave
72 72 translate 
89.999 rotate 
/Helvetica findfont 24 scalefont setfont 
0 0 moveto 
(Some Postscript Text) show 
grestore

It works!

So, to adapt to this problem, I had to add a special case to the PPML output: if the angle would be written as 90, 180, 270, etc., subtract/add .001.

In short, due to a bug in another piece of software, my software has extra code for a workaround hack.