Skip to content

Conversation

@trevnorris
Copy link
Contributor

Re-add the wrapper class id to AsyncWrap instances so they can be
tracked directly in a heapdump.

Previously the class id was given without setting the heap dump wrapper
class info provider. Causing a segfault when a heapdump was taken. This
has been added, and the label_ set to the given provider name so each
instance can be identified.

R=@bnoordhuis

For performance testing I ran the following:

varJSStream=process.binding('js_stream').JSStream;varITER=1e7;vart=process.hrtime();for(vari=0;i<ITER;i++)newJSStream();t=process.hrtime(t);console.log(((t[0]*1e9+t[1])/ITER).toFixed(1)+' ns/op');

It was the most direct way I found to instantiate a new AsyncWrap instance from JS. It shows no performance degradation with this patch applied.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I'd prefer to unwrap the instance as the given provider type that's passed, but am coming up short on the necessary syntax.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

guess I could do a massive switch statement, but that feels wrong.

@mscdexmscdex added the c++ Issues and PRs that require attention from people who are familiar with C++. label Jun 4, 2015
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm feeling a little bit un-easy about the magic Class Ids.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a deterministic way to generate a class id? that's pretty much how it's done everywhere else in core.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

smalloc is the only other example I can find. We could maintain a central table for classIds. The danger that I am thinking about is if user-space modules need to use use classIds as well and happen to use the same value. It would be nice if one (i.e. user-space or core) could request a classId from the table. That way we can be sure that there won't be collisions.

I am only 'a little bit un-easy', and don't have objections to this PR landing as is.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Think that's definitely a PR to explore.

@trevnorristrevnorrisforce-pushed the pass-provider-and-cb branch from 0a87ffd to e0268e3CompareJune 4, 2015 17:42
src/node.js Outdated
Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to just run SetWrapperClassInfoProvider() from node.cc, but then I'd have to migrate all the RetainedAsyncInfo logic as well. Thoughts on a better solution?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you export a function in src/async-wrap.cc and call that in src/node.cc?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oop. Missed this comment. Sounds like a much better alternative.

@bnoordhuis
Copy link
Member

I see two issues with this PR.

  1. It reports the wrong size for instances, it's always sizeof(AsyncWrap). That's wrong in general and very wrong for variable length types like WriteWrap.
  2. It heap-allocates a new RetainedAsyncInfo for every instance and that:

2a. Wastes memory because most instances have a static layout and size.

2b. Probably slows down heap snapshots. RetainedAsyncInfo::IsEquivalent() only considers RetainedAsyncInfo instances equivalent when they point to the same AsyncWrap instance instead of instances of the same class. The heap snapshot generator has to do more work because of that although I don't know exactly how much more.

2a and 2b probably aren't that significant so long as there aren't too many AsyncWrap instances but 1 most definitely is.

@trevnorris
Copy link
ContributorAuthor

@bnoordhuis I should have labeled this as WIP. Knew before it was posted that the implementation was incomplete.

(1) was my biggest concern while writing this patch, and something I couldn't figure out on my own. Was hoping you'd have a suggestion about how to potentially get around it.

Wasn't aware of the issues pointed out in (2). Most of the implementation was pulled directly out of smalloc.cc, which originally came from your implementation in 6a128e0. I'll be more than happy to work on both those points if you think other issues in this PR can be worked out.

@bnoordhuis
Copy link
Member

I think the easiest solution to (1) is to add a virtual size_t self_size() const = 0; pure virtual method to AsyncWrap and have descendants implement that. For most, return sizeof(*this); will suffice.

Regarding (2), it would help to have static RetainedAsyncInfo instances for statically sized classes but that can be done as a future optimization.

@trevnorristrevnorrisforce-pushed the pass-provider-and-cb branch 6 times, most recently from 67b3114 to 6965730CompareJune 8, 2015 23:00
@trevnorris
Copy link
ContributorAuthor

@bnoordhuis Thanks for the reviews. Finished fixing the last round.

While I've been wanting a means to do this (furthering use of AsyncWrap and all that), the patch became more invasive then I imaged it would be. If you can think of a more graceful implementation I'll redo this from scratch if necessary.

@trevnorristrevnorrisforce-pushed the pass-provider-and-cb branch 2 times, most recently from 9c78909 to c47c024CompareJune 9, 2015 22:50
@trevnorris
Copy link
ContributorAuthor

@trevnorris
Copy link
ContributorAuthor

All test failures are the same:

not ok 105 - test-cluster-worker-wait-server-close.js 

I doubt it's related to this PR, but don't know for sure.

@jbergstroem
Copy link
Member

@trevnorris the test seems to time out as well.

@trevnorris
Copy link
ContributorAuthor

@jbergstroem Thank for pointing that out.

@Olegas
Copy link
Contributor

I know this test. It's mine. It was kinda broken while #1400 is merged.

@trevnorristrevnorrisforce-pushed the pass-provider-and-cb branch 3 times, most recently from 0890f6c to a511c2eCompareJune 10, 2015 23:14
@trevnorris
Copy link
ContributorAuthor

@trevnorristrevnorrisforce-pushed the pass-provider-and-cb branch from a511c2e to 49d168bCompareJune 11, 2015 02:29
@trevnorris
Copy link
ContributorAuthor

And again. Something went strange w/ my force push last time.

https://jenkins-iojs.nodesource.com/job/iojs+any-pr+multi/799/

@trevnorris
Copy link
ContributorAuthor

CI completed. Same failures as before. None related to this patch.

@bnoordhuis if you're okay with the fixes, mind if I merge this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic constant.

@trevnorristrevnorrisforce-pushed the pass-provider-and-cb branch from 49d168b to bb669c4CompareJune 15, 2015 21:40
@trevnorris
Copy link
ContributorAuthor

@bnoordhuis Thanks much for the additional review. All points have been addressed.

Re-add the wrapper class id to AsyncWrap instances so they can be tracked directly in a heapdump. Previously the class id was given without setting the heap dump wrapper class info provider. Causing a segfault when a heapdump was taken. This has been added, and the label_ set to the given provider name so each instance can be identified. The id will not be set of the passed object has no internal field count. As the class pointer cannot be retrieved from the object. In order to properly report the allocated size of each class, the new pure virtual method self_size() has been introduces.
@trevnorristrevnorrisforce-pushed the pass-provider-and-cb branch from bb669c4 to 5e792aaCompareJune 17, 2015 18:07
@trevnorris
Copy link
ContributorAuthor

@bnoordhuis
Copy link
Member

LGTM at a glance.

@trevnorris
Copy link
ContributorAuthor

Getting the following from centos5-32:

not ok 532 - test-process-argv-0.js # argv=["/home/iojs/build/workspace/iojs+pr+linux/nodes/centos5-32/out/Release/iojs","/home/iojs/build/workspace/iojs+pr+linux/nodes/centos5-32/test/parallel/test-process-argv-0.js"] # exec="/home/iojs/build/workspace/iojs+pr+linux/nodes/centos5-32/out/Release/iojs" # CHILD: argv=["/home/iojs/build/workspace/iojs+pr+linux/nodes/centos5-32/out/Release/iojs","/home/iojs/build/workspace/iojs+pr+linux/nodes/centos5-32/test/parallel/test-process-argv-0.js","child"] # # assert.js:89 # throw new assert.AssertionError({# ^ # AssertionError: '' == '/home/iojs/build/workspace/iojs+pr+linux/nodes/centos5-32/out/Release/iojs' # at ChildProcess.<anonymous> (/home/iojs/build/workspace/iojs+pr+linux/nodes/centos5-32/test/parallel/test-process-argv-0.js:26:12) # at emitTwo (events.js:87:13) # at ChildProcess.emit (events.js:172:7) # at Process.ChildProcess._handle.onexit (internal/child_process.js:200:12) 

Don't know how it could be related, so going to say that tests are looking good.

trevnorris added a commit that referenced this pull request Jun 17, 2015
Re-add the wrapper class id to AsyncWrap instances so they can be tracked directly in a heapdump. Previously the class id was given without setting the heap dump wrapper class info provider. Causing a segfault when a heapdump was taken. This has been added, and the label_ set to the given provider name so each instance can be identified. The id will not be set of the passed object has no internal field count. As the class pointer cannot be retrieved from the object. In order to properly report the allocated size of each class, the new pure virtual method self_size() has been introduces. PR-URL: #1896 Reviewed-By: Ben Noordhuis <[email protected]>
@trevnorris
Copy link
ContributorAuthor

Landed in e56758a.

Thanks @bnoordhuis for the reviews.

@trevnorristrevnorris deleted the pass-provider-and-cb branch June 17, 2015 19:04
@rvaggrvagg mentioned this pull request Jun 18, 2015
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++Issues and PRs that require attention from people who are familiar with C++.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@trevnorris@bnoordhuis@jbergstroem@Olegas@ofrobots@mscdex