Created
October 31, 2010 20:44
-
-
Save justinvh/657118 to your computer and use it in GitHub Desktop.
A V8 Developer Talk in Global Objects and Templates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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