Skip to content

Commit

Permalink
Make use of better heap tagging in cmpctmalloc (#170)
Browse files Browse the repository at this point in the history
* Make use of better heap tagging in cmpctmalloc
  • Loading branch information
Erik Corry authored Dec 20, 2021
1 parent e6b24c4 commit 04c8c7a
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 13 deletions.
4 changes: 3 additions & 1 deletion src/heap_report.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ static const uint8 UNKNOWN_MALLOC_TAG = 9;
static const uint8 EVENT_SOURCE_MALLOC_TAG = 10;
static const uint8 OTHER_THREADS_MALLOC_TAG = 11;
static const uint8 THREAD_SPAWN_MALLOC_TAG = 12;
static const uint8 NUMBER_OF_MALLOC_TAGS = 13;
static const uint8 NULL_MALLOC_TAG = 13;
static const uint8 WIFI_MALLOC_TAG = 14;
static const uint8 NUMBER_OF_MALLOC_TAGS = 15;

#ifdef TOIT_CMPCTMALLOC

Expand Down
7 changes: 5 additions & 2 deletions src/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ class OS {
// If we are using Cmpctmalloc this lets us set a tag that is used to mark
// the origin of allocations on the current thread.
static void set_heap_tag(word tag);
static void clear_heap_tag();
static word get_heap_tag();
static void heap_summary_report();

// Unique 16-bytes uuid of the running image.
Expand All @@ -245,12 +245,15 @@ class OS {
class HeapTagScope {
public:
HeapTagScope(uword tag) {
old = OS::get_heap_tag();
OS::set_heap_tag(tag);
}

~HeapTagScope() {
OS::clear_heap_tag();
OS::set_heap_tag(old);
}

uword old;
};

} // namespace toit
Expand Down
2 changes: 1 addition & 1 deletion src/os_darwin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ int OS::read_entire_file(char* name, uint8** buffer) {
}

void OS::set_heap_tag(word tag) { }
void OS::clear_heap_tag() { }
word OS::get_heap_tag() { return 0; }
void OS::heap_summary_report() { }

}
Expand Down
20 changes: 15 additions & 5 deletions src/os_esp32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ void OS::set_heap_tag(word tag) {
heap_caps_set_option(MALLOC_OPTION_THREAD_TAG, reinterpret_cast<void*>(tag));
}

void OS::clear_heap_tag() {
heap_caps_set_option(MALLOC_OPTION_THREAD_TAG, null);
word OS::get_heap_tag() {
return reinterpret_cast<word>(heap_caps_get_option(MALLOC_OPTION_THREAD_TAG));
}

class HeapSummaryPage {
Expand Down Expand Up @@ -447,7 +447,11 @@ class HeapSummaryPage {

int register_user(uword tag, uword size) {
uint16 saturated_size = Utils::min(size, 0xffffu);
if (tag == ITERATE_TAG_FREE) {
if (tag == 0) {
tag = NULL_MALLOC_TAG;
} else if (tag == 'W') {
tag = WIFI_MALLOC_TAG;
} else if (tag == ITERATE_TAG_FREE) {
tag = FREE_MALLOC_TAG;
} else {
tag -= ITERATE_CUSTOM_TAGS;
Expand Down Expand Up @@ -490,6 +494,8 @@ class HeapSummaryPage {
case EVENT_SOURCE_MALLOC_TAG: return "event source";
case OTHER_THREADS_MALLOC_TAG: return "other threads";
case THREAD_SPAWN_MALLOC_TAG: return "thread spawn";
case NULL_MALLOC_TAG: return "null tag";
case WIFI_MALLOC_TAG: return "wifi";
}
return "unknown";
}
Expand Down Expand Up @@ -517,6 +523,10 @@ class HeapSummaryCollector {
memset(void_cast(counts_), 0, sizeof counts_);
}

word allocation_requirement() {
return MAX_PAGES_ * sizeof(HeapSummaryPage);
}

bool out_of_memory() const { return pages_ == null; }

~HeapSummaryCollector() {
Expand Down Expand Up @@ -570,7 +580,7 @@ bool register_allocation(void* self, void* tag, void* address, uword size) {
void OS::heap_summary_report() {
HeapSummaryCollector collector;
if (collector.out_of_memory()) {
printf("Not enough memory for a heap report\n");
printf("Not enough memory for a heap report (%d bytes)\n", static_cast<int>(collector.allocation_requirement()));
return;
}
int flags = ITERATE_ALL_ALLOCATIONS | ITERATE_UNALLOCATED;
Expand All @@ -581,7 +591,7 @@ void OS::heap_summary_report() {
#else // def TOIT_CMPCTMALLOC

void OS::set_heap_tag(word tag) { }
void OS::clear_heap_tag() { }
word OS::get_heap_tag() { return 0; }
void OS::heap_summary_report() { }


Expand Down
7 changes: 4 additions & 3 deletions src/os_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -116,18 +116,19 @@ void OS::set_heap_tag(word tag) {
}
}

void OS::clear_heap_tag() {
word OS::get_heap_tag() {
int MALLOC_OPTION_THREAD_TAG = 1;
if (heap_caps_set_option != null) {
heap_caps_set_option(MALLOC_OPTION_THREAD_TAG, null);
return reinterpret_cast<word>(heap_caps_get_option(MALLOC_OPTION_THREAD_TAG));
}
return 0;
}


#else // def TOIT_CMPCTMALLOC

void OS::set_heap_tag(word tag) { }
void OS::clear_heap_tag() { }
word OS::get_heap_tag() { return 0; }

#endif // def TOIT_CMPCTMALLOC

Expand Down
2 changes: 1 addition & 1 deletion src/os_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ int OS::read_entire_file(char* name, uint8** buffer) {

void OS::set_heap_tag(word tag) {}

void OS::clear_heap_tag() {}
word OS::get_heap_tag() { return 0; }

} // namespace toit

Expand Down
1 change: 1 addition & 0 deletions src/resources/tls.cc
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ bool ensure_handshake_memory() {
// restarted from scratch. This is annoying, but most code will already be
// able to restart TLS connections since they can fail because of transient
// network issues.
HeapTagScope scope(ITERATE_CUSTOM_TAGS + BIGNUM_MALLOC_TAG);
const int BLOCK_SIZE = 1900;
const int BLOCK_COUNT = 8;
void* blocks[BLOCK_COUNT] = { 0 };
Expand Down
1 change: 1 addition & 0 deletions src/resources/x509.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ PRIMITIVE(init) {

PRIMITIVE(parse) {
ARGS(X509ResourceGroup, resource_group, Object, input);
HeapTagScope scope(ITERATE_CUSTOM_TAGS + BIGNUM_MALLOC_TAG);

const uint8_t* data = null;
size_t length = 0;
Expand Down

0 comments on commit 04c8c7a

Please sign in to comment.