Skip to content

Instantly share code, notes, and snippets.

@justinvh
Created October 31, 2010 20:44
Show Gist options
  • Save justinvh/657118 to your computer and use it in GitHub Desktop.
Save justinvh/657118 to your computer and use it in GitHub Desktop.
A V8 Developer Talk in Global Objects and Templates
Session Start: Sun Oct 31 11:52:15 2010
Session Ident: #v8
15[11:52:15] * Now talking in #v8
03[11:52:15] * Topic is 'see #chromium, http://code.google.com/p/v8/'
03[11:52:15] * Set by mal on Tue Sep 02 12:03:02
[11:54:41] <mraleph> justinvh: hi! i don't see SetInternalFieldCount being called in your code. that's seems broken to me :-)
07[11:54:43] <justinvh> Allright. mraleph -- Always a pleasure to talk :)
[11:55:51] <mraleph> justinvh: same here :-)
07[11:56:30] <justinvh> Anyhow, I wasn't storing anything internally to that object. I can see the check that goes bad happens to be with that index, but it happens when I am instantiating the context...
07[11:56:52] <justinvh> Literally: ObjectTemplate::New() and then creating a context.
07[11:57:19] <justinvh> I swapped some redundant code around to just have the scope creating and then the persistent context. I'll show you the code itself.
[11:57:38] <mraleph> well you store something later on line 150
07[11:58:08] <justinvh> Yes, but at that point that count has been set through magic.
07[11:58:18] <justinvh> wrap_tmpl() has some stuff behind the scenes that does that all.
[11:58:20] <mraleph> russiane39: just send whatever bt you have.
[11:58:29] <mraleph> holy cow
[11:58:31] <mraleph> ok
07[11:58:51] <justinvh> Sorry -- Let me minimize some stuff and I'll push latest changes so we can really look at it.
07[11:59:53] <justinvh> Ah, I see your statement mraleph -- Sorry, I understand what you mean now.
07[12:00:07] <justinvh> I have no idea how I forgot that. I thought I had russiane39 put that in for testing as well though.
[12:00:18] <mraleph> hmm. are you sure that you don't create any instances from template before calling SetInternalFieldCount?
07[12:00:38] <justinvh> russiane39: When you added the global_scope->SetInternalFieldCount(1) after the global_scope instantiation did it still break?
[12:00:46] <russiane39> justinvh, yes
[12:00:50] <mraleph> API is not my strongest part though --- I am looking from inside ;-)
[12:01:19] <mraleph> russiane39: stacktrace please =)
[12:03:27] <russiane39> justinvh, tell mraleph why stacktrace is useless here :)
07[12:03:32] <justinvh> mraleph: http://github.com/justinvh/Rogue-Reborn/blob/master/gui/src/gui.cpp
07[12:04:24] <justinvh> Oh, heh, old quake 3 code base uses setjmp when there is a bad error. Stack gets pretty messy. You can set a break on that line that it states the error in in the internal field check and then just manually do a bt at that break point
[12:04:58] <mraleph> yep. that's what I want
[12:05:29] <russiane39> ok, should I try it
07[12:05:37] <justinvh> Go for it.
07[12:05:56] <justinvh> running between kitchen and keyboard.
[12:06:26] <mraleph> justinvh: heh. fortunately I have both in the same room :-)
07[12:06:36] <justinvh> I have a case of stairs between mine.
07[12:07:56] <justinvh> The global_context->Global() is done because I was trying to isolate the issue with russiane39. So it's intentionally after the context_scope is declared.
07[12:10:57] <justinvh> Wait -- I don't know if this was said, but this is being run out of stable.
[12:11:07] <russiane39> it's 2.5.2
[12:11:21] <russiane39> oh, 2.5.1
[12:11:21] <russiane39> sorry
07[12:11:56] <justinvh> Hence a bunch of the oddities like ->Get(v8::Int32::New) being used.
[12:12:21] <russiane39> Breakpoint 1, v8::internal::JSObject::SetInternalField (this=0x7fffbe041b89, index=0, value=0x7fffbe041bb1) at src/objects-inl.h:1266
[12:12:21] <russiane39> 1266 ASSERT(index < GetInternalFieldCount() && index >= 0);
[12:12:21] <mraleph> well i don't remember any serious fixes being pushed between 2.5.2 and 2.5.1
[12:12:47] <mraleph> russiane39: bt
[12:13:15] <russiane39> #0 v8::internal::JSObject::SetInternalField (this=0x7fffbe041b89, index=0, value=0x7fffbe041bb1) at src/objects-inl.h:1266
[12:13:15] <russiane39> #1 0x00007fffc1715e1b in v8::Object::SetInternalField (this=0x94d5038, index=0, value=...) at src/api.cc:3203
[12:13:15] <russiane39> #2 0x00007fffc1d3e25d in hat::Gui::wrap_tmpl(v8::Handle<v8::FunctionTemplate>*, hat::Gui*, void (*)(v8::Handle<v8::ObjectTemplate>*)) () from /home/russiane39/Projects/rr-gcc/base/gui.so
[12:13:15] <russiane39> #3 0x00007fffc1d3bed0 in hat::Gui::Gui(char const*) () from /home/russiane39/Projects/rr-gcc/base/gui.so
[12:13:16] <russiane39> #4 0x00007fffc1d311e5 in vmMain () from /home/russiane39/Projects/rr-gcc/base/gui.so
[12:13:32] <russiane39> bt full
[12:13:32] <russiane39> #0 v8::internal::JSObject::SetInternalField (this=0x7fffbe041b89, index=0, value=0x7fffbe041bb1) at src/objects-inl.h:1266
[12:13:32] <russiane39> offset = 32767
[12:13:32] <russiane39> #1 0x00007fffc1715e1b in v8::Object::SetInternalField (this=0x94d5038, index=0, value=...) at src/api.cc:3203
[12:13:32] <russiane39> obj = {location_ = 0x94d5038}
[12:13:33] <russiane39> __state__ = {<v8::internal::Embedded> = {<No data fields>}, disabled_ = true, state_ = v8::internal::OTHER, previous_ = 0x7fffffffde60, external_callback_ = 0x0}
[12:13:36] <russiane39> val = {location_ = 0x94d5040}
[12:14:07] <mraleph> print this->Print()
[12:14:22] <mraleph> this is debug build of v8 right?
[12:14:33] <mraleph> should be if were a hitting assertion
[12:14:40] <russiane39> yes, this is debug build
[12:15:35] <mraleph> well there is another tmpl being created in wrap_tmpl as I see
[12:15:50] <mraleph> you should also SetInternalFieldCount for it
07[12:16:16] <justinvh> It gets set.
07[12:16:29] <justinvh> Line 54 in easy.cpp
07[12:16:44] <justinvh> I promise I match them up.
07[12:16:56] <justinvh> But, definitely check.
07[12:17:39] <justinvh> Ah, I set it to 2 -- Older code, but that shouldn't make a difference, right?
07[12:17:46] <justinvh> Since the index being set is 0
[12:17:49] <mraleph> hmm indeed
[12:18:46] <mraleph> strange
07[12:19:33] <justinvh> russiane39: Can you pull my latest changes and re-run that bt
[12:19:38] <russiane39> justinvh, yes
07[12:19:48] <justinvh> At the point of the assertion no other ObjetTemplates have been created.
07[12:19:52] <justinvh> Only global_scope
07[12:19:59] <justinvh> global_scope is created
07[12:20:07] <justinvh> global_scope internalfieldcount is set
07[12:20:09] <justinvh> assertion failure
[12:20:29] <mraleph> russiane39: can you do print this->Print() in gdb while you are on break?
[12:20:34] <russiane39> mraleph, sure
[12:21:43] <russiane39> (gdb) print this->Print()
[12:21:43] <russiane39> 0x7fffbe041341: [JSObject]
[12:21:43] <russiane39> - map = 0x7fffc3b199d1
[12:21:43] <russiane39> - prototype = 0x7fffbe03fb01
[12:21:43] <russiane39> {
[12:21:44] <russiane39> }
[12:21:46] <russiane39> $1 = void
[12:21:54] <russiane39> (gdb) bt
[12:21:54] <russiane39> #0 v8::internal::JSObject::SetInternalField (this=0x7fffbe041341, index=0, value=0x7fffbe041369) at src/objects-inl.h:1266
[12:21:55] <russiane39> #1 0x00007fffc14b5e1b in v8::Object::SetInternalField (this=0x950db98, index=0, value=...) at src/api.cc:3203
[12:21:57] <russiane39> #2 0x00007fffc1adf915 in Gui::wrap_tmpl (tmpl=0x7fffffffdeb8, e=0x7fffffffde80, extension=0) at /home/russiane39/Projects/RR/gui/src/gui.cpp:495
[12:22:00] <russiane39> #3 0x00007fffc1ae44fa in Gui::__comp_ctor (this=0x7fffffffde80, js_file=0x7fffc1af32c0 "javascript/gui/init.js") at /home/russiane39/Projects/RR/gui/src/gui.cpp:149
[12:22:03] <russiane39> #4 0x00007fffc1accfcb in vmMain (command=1, arg0=0, arg1=-134477920, arg2=4, arg3=-7904, arg4=0, arg5=5464379, arg6=8, arg7=5108134, arg8=-7856, arg9=5060847, arg10=-8016, arg11=-8224)
[12:22:06] <russiane39> at /home/russiane39/Projects/RR/gui/src/ui_main.cpp:109
[12:22:08] <russiane39> #5 0x0000000000551740 in VM_Call (vm=0x75ee720, callnum=1) at /home/russiane39/Projects/RR/engine/src/vm.c:284
[12:22:10] <russiane39> #6 0x00000000004defef in CL_InitUI () at /home/russiane39/Projects/RR/engine/src/cl_ui.c:1279
[12:22:12] <russiane39> #7 0x00000000004d38ef in CL_StartHunkUsers (rendererOnly=qfalse) at /home/russiane39/Projects/RR/engine/src/cl_main.c:3215
[12:22:15] <russiane39> #8 0x00000000004fff37 in Com_Init (commandLine=0x7fffffffe1e0 "") at /home/russiane39/Projects/RR/engine/src/common.c:3904
[12:22:18] <russiane39> #9 0x000000000054e16f in main (argc=1, argv=0x7fffffffe6e8) at /home/russiane39/Projects/RR/engine/src/sys_main.c:649
07[12:22:45] <justinvh> Oh
07[12:22:50] <justinvh> Neat.
07[12:23:52] <justinvh> I assumed when I created the new instance that the internalfieldcount would carry over.
07[12:24:00] <justinvh> Am I wrong asserting this?
[12:24:17] <mraleph> no it should be
[12:24:48] <mraleph> print this->GetPrototype()->Print()
07[12:25:57] <justinvh> mraleph: http://github.com/justinvh/Rogue-Reborn/blob/master/gui/src/easy.cpp
07[12:26:08] <justinvh> Lines 13 on are where the accessors and functions get set.
07[12:26:13] <justinvh> Also where the internalfieldcount is set.
[12:27:17] <mraleph> justinvh: yep. I looked there. looks correct.
[12:27:31] <russiane39> (gdb) print this->GetPrototype()->Print()
[12:27:32] <russiane39> Attempt to dereference a generic pointer.
[12:29:00] <mraleph> hmm. gdb is broken :(
[12:30:51] <russiane39> (gdb) c
[12:30:51] <russiane39> Continuing.
[12:30:51] <russiane39> Breakpoint 1, v8::internal::JSObject::SetInternalField (this=0x7fffc3b96961, index=0, value=0x7fffffffde80) at src/objects-inl.h:1266
[12:30:51] <russiane39> 1266 ASSERT(index < GetInternalFieldCount() && index >= 0);
[12:30:59] <russiane39> I can get another backtrace
07[12:31:54] <justinvh> Hm -- I realized I am running 2.4.7 now under Windows; sigh. Cross-builds and maintaining this stuff. Okay, maybe I can help as well. Give me a few minutes.
[12:32:12] <mraleph> I am still digging into sources =)
07[12:32:38] <justinvh> Hah, well, thanks a lot. I feel like I try to make v8 do things it shouldn't do :)
07[12:32:52] <justinvh> "Come on team. Multiple inheritance and threading. Get it done"
[12:33:53] <russiane39> http://pastebin.mozilla.org/832490
[12:33:58] <russiane39> that's bt full from second step
07[12:47:44] <justinvh> Sigh - I get unresolved external symbols when I try to link with v8 -- Including the samples.
07[12:47:51] <justinvh> double __cdecl v8::internal::Strtod(class v8::internal::Vector<char const >,int)
07[12:47:56] <justinvh> public: static void __cdecl v8::internal::PowersOfTenCache::GetCachedPowerForBinaryExponentRange
[12:48:06] <mraleph> hmm.
[12:48:29] <mraleph> something omitted from the build
07[12:48:48] <justinvh> Yeah, I'll give the scons one a try -- Under windows so I default'd to the VS builds.
[12:49:18] <mraleph> fast-dtoa/fixed-dtoa
[12:49:45] <mraleph> cached-powers.cc
07[12:49:46] <justinvh> fast-dtoa and conversions are where the errors are coming out of.
[12:50:06] <mraleph> yep I realized that
[12:50:42] <mraleph> probably we forgot to update MSVS project files with all refactoring going on in dtoa --- add cached-powers.cc
[12:51:53] <mraleph> Strtod seems to be in strod.cc
15[12:52:19] * russiane39 has quit IRC (Quit: Leaving)
[12:53:31] <mraleph> after some digging in the code I still can't understand where the problem comes from. You call SetInternalFieldsCount pretty early long befor calling to GetFunction() so it should everything should work like a charm
07[13:00:51] <justinvh> I'll check it more -- Still dealing with unresolved symbols.
07[13:09:38] <justinvh> Awesome - I get the error too.
[13:11:21] <mraleph> great, now you can debug it =)
07[13:11:27] <justinvh> Indeed.
07[13:14:14] <justinvh> mraleph: Should this assertion pass: object = ObjectTemplate::New(), Persistent<Context> context = Context::New(NULL, object); assert(context->Global() == object);
07[13:14:26] <justinvh> Or can I compare objects like that -- Should I deference the handle?
[13:14:46] <mraleph> bt.
[13:14:49] <mraleph> btw
[13:15:10] <mraleph> i just found some code
[13:15:54] <mraleph> that shows that object will be template to prototype of global object not template of global object as your code expects.
[13:16:19] <mraleph> let me find a link for you
[13:18:01] <mraleph> http://code.google.com/p/v8/source/browse/trunk/test/cctest/test-api.cc#1470
[13:18:34] <mraleph> *sigh* google code syntax highlighting is kinda slow...
07[13:18:44] <justinvh> It's alright.
07[13:18:55] <justinvh> Ahhh
07[13:19:24] <justinvh> Can you explain that a bit more. Why can't I assume that since I specified the internalfieldcount as 1 for the object template itself that I have to still return the prototype
07[13:20:02] <justinvh> Tricky looking line.
[13:20:14] <mraleph> this seems to be specific for global objects
[13:20:44] <mraleph> for some reason global_template is not used to create global objects
[13:21:06] <mraleph> instead we create a proxy which has object created from global_template as a prototype
[13:21:33] <mraleph> this all was designed before the dawn of time so I don't know why!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment