Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: start the .text section with an asm symbol #31981

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 20 additions & 0 deletions node.gyp
Expand Up @@ -313,6 +313,19 @@
},

'targets': [
{
'target_name': 'node_text_start',
'type': 'none',
'conditions': [
[ 'OS=="linux" and '
'target_arch=="x64"', {
'type': 'static_library',
'sources': [
'src/large_pages/node_text_start.S'
]
}],
]
},
{
'target_name': '<(node_core_target_name)',
'type': 'executable',
Expand Down Expand Up @@ -498,6 +511,13 @@
'src/node_snapshot_stub.cc'
],
}],
[ 'OS=="linux" and '
'target_arch=="x64"', {
'dependencies': [ 'node_text_start' ],
'ldflags+': [
'<(PRODUCT_DIR)/obj.target/node_text_start/src/large_pages/node_text_start.o'
]
}],
],
}, # node_core_target_name
{
Expand Down
29 changes: 15 additions & 14 deletions src/large_pages/node_large_page.cc
Expand Up @@ -71,7 +71,11 @@

#if defined(__linux__)
extern "C" {
extern char __executable_start;
// This symbol must be declared weak because this file becomes part of all
// Node.js targets (like node_mksnapshot, node_mkcodecache, and cctest) and
// those files do not supply the symbol.
extern char __attribute__((weak)) __node_text_start;
extern char __start_lpstub;
} // extern "C"
#endif // defined(__linux__)

Expand Down Expand Up @@ -121,6 +125,8 @@ struct text_region FindNodeTextRegion() {
std::string dev;
char dash;
uintptr_t start, end, offset, inode;
uintptr_t node_text_start = reinterpret_cast<uintptr_t>(&__node_text_start);
uintptr_t lpstub_start = reinterpret_cast<uintptr_t>(&__start_lpstub);

ifs.open("/proc/self/maps");
if (!ifs) {
Expand All @@ -144,21 +150,16 @@ struct text_region FindNodeTextRegion() {
std::string pathname;
iss >> pathname;

if (start != reinterpret_cast<uintptr_t>(&__executable_start))
if (permission != "r-xp")
continue;

// The next line is our .text section.
if (!std::getline(ifs, map_line))
break;

iss = std::istringstream(map_line);
iss >> std::hex >> start;
iss >> dash;
iss >> std::hex >> end;
iss >> permission;
if (node_text_start < start || node_text_start >= end)
continue;

if (permission != "r-xp")
break;
start = node_text_start;
if (lpstub_start > start && lpstub_start <= end) {
end = lpstub_start;
}
gabrielschulhof marked this conversation as resolved.
Show resolved Hide resolved

char* from = reinterpret_cast<char*>(hugepage_align_up(start));
char* to = reinterpret_cast<char*>(hugepage_align_down(end));
Expand Down Expand Up @@ -318,7 +319,7 @@ static bool IsSuperPagesEnabled() {
// d. If successful copy the code there and unmap the original region
int
#if !defined(__APPLE__)
__attribute__((__section__(".lpstub")))
__attribute__((__section__("lpstub")))
#else
__attribute__((__section__("__TEXT,__lpstub")))
#endif
Expand Down
5 changes: 5 additions & 0 deletions src/large_pages/node_text_start.S
@@ -0,0 +1,5 @@
.text
.align 0x2000
Copy link
Member

Choose a reason for hiding this comment

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

Why 8k?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good question, actually. I'm not sure we need it, because we end up snipping the front and the back off the .text if it doesn't align at 2MiB anyway, leaving the snipped-off bits on 4KiB pages.

.global __node_text_start
.hidden __node_text_start
__node_text_start: