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

Fix side_function on K Match on GDB #741

Merged
merged 6 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions debug/kgdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -760,8 +760,11 @@ def invoke(self, arg, from_tty):
if entry['kind'] == self.SUCCESS:
print('Match succeeds')
elif entry['kind'] == self.FUNCTION:
print(entry['debugName'].string("iso-8859-1") + '(', end='')
function = gdb.lookup_global_symbol(entry['function'].string("iso-8859-1")).value().type
debugFunctionName = entry['debugName'].string("iso-8859-1")
functionName = entry['function'].string("iso-8859-1")
print(debugFunctionName + '(', end='')
name = functionName if functionName[:5] == 'hook_' else debugFunctionName
function = gdb.lookup_global_symbol(name).value().type
front = gdb.lookup_global_symbol("getMatchFnArgs").value()(entry.address)
conn = ""
for i in range(len(function.fields())):
Expand Down
1 change: 1 addition & 0 deletions include/runtime/header.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct MatchLog {
#define size_hdr(s) ((((s) >> 32) & 0xff) * 8)
#define layout(s) layout_hdr((s)->h.hdr)
#define layout_hdr(s) ((s) >> LAYOUT_OFFSET)
#define tag(s) tag_hdr((s)->h.hdr)
#define tag_hdr(s) (s & TAG_MASK)
#define is_in_young_gen_hdr(s) (!((s)&NOT_YOUNG_OBJECT_BIT))
#define is_in_old_gen_hdr(s) (((s)&NOT_YOUNG_OBJECT_BIT) && ((s)&AGE_MASK))
Expand Down
1 change: 0 additions & 1 deletion runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")

file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/main)
configure_file(main/main.ll ${CMAKE_CURRENT_BINARY_DIR}/main @ONLY)
configure_file(equality.ll ${CMAKE_CURRENT_BINARY_DIR} @ONLY)
configure_file(finish_rewriting.ll ${CMAKE_CURRENT_BINARY_DIR} @ONLY)
configure_file(fresh.ll ${CMAKE_CURRENT_BINARY_DIR} @ONLY)
configure_file(getTag.ll ${CMAKE_CURRENT_BINARY_DIR} @ONLY)
Expand Down
1 change: 1 addition & 0 deletions runtime/collections/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_library(collections STATIC
kelemle.cpp
lists.cpp
maps.cpp
sets.cpp
Expand Down
224 changes: 224 additions & 0 deletions runtime/collections/kelemle.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
#include "runtime/header.h"

extern "C" {
bool hook_MAP_eq(SortMap, SortMap);
bool hook_LIST_eq(SortList, SortList);
bool hook_SET_eq(SortSet, SortSet);
bool hook_INT_eq(SortInt, SortInt);
bool hook_FLOAT_trueeq(SortFloat, SortFloat);
bool hook_STRING_lt(SortString, SortString);

bool hook_KEQUAL_eq(block *arg1, block *arg2) {
uint64_t arg1intptr = (uint64_t)arg1;
uint64_t arg2intptr = (uint64_t)arg2;
bool arg1lb = is_leaf_block(arg1intptr);
bool arg2lb = is_leaf_block(arg2intptr);
if (arg1lb == arg2lb) {
if (arg1lb) {
// Both arg1 and arg2 are constants.
return arg1intptr == arg2intptr;
} else {
// Both arg1 and arg2 are blocks.
uint64_t arg1hdrcanon = arg1->h.hdr & HDR_MASK;
uint64_t arg2hdrcanon = arg2->h.hdr & HDR_MASK;
if (arg1hdrcanon == arg2hdrcanon) {
// Canonical headers of arg1 and arg2 are equal.
// Both arg1 and arg2 are either strings or symbols.
uint64_t arglayout = layout(arg1);
if (arglayout == 0) {
// Both arg1 and arg2 are strings.
return hook_STRING_eq((string *)arg1, (string *)arg2);
} else { // arglayout != 0
// Both arg1 and arg2 are blocks.
uint16_t arglayoutshort = (uint16_t)arglayout;
layout *layoutPtr = getLayoutData(arglayoutshort);
uint8_t length = layoutPtr->nargs;
for (uint8_t i = 0; i < length; i++) {
uint64_t offset = layoutPtr->args[i].offset;
uint64_t child1intptr = arg1intptr + offset;
uint64_t child2intptr = arg2intptr + offset;
uint16_t cat = layoutPtr->args[i].cat;
switch (cat) {
case MAP_LAYOUT: {
map *map1ptr = (map *)(child1intptr);
map *map2ptr = (map *)(child2intptr);
bool cmp = hook_MAP_eq(map1ptr, map2ptr);
if (!cmp) {
return false;
}
break;
}
case LIST_LAYOUT: {
list *list1ptr = (list *)(child1intptr);
list *list2ptr = (list *)(child2intptr);
bool cmp = hook_LIST_eq(list1ptr, list2ptr);
if (!cmp) {
return false;
}
break;
}
case SET_LAYOUT: {
set *set1ptr = (set *)(child1intptr);
set *set2ptr = (set *)(child2intptr);
bool cmp = hook_SET_eq(set1ptr, set2ptr);
if (!cmp) {
return false;
}
break;
}
case INT_LAYOUT: {
mpz_ptr *int1ptrptr = (mpz_ptr *)(child1intptr);
mpz_ptr *int2ptrptr = (mpz_ptr *)(child2intptr);
bool cmp = hook_INT_eq(*int1ptrptr, *int2ptrptr);
if (!cmp) {
return false;
}
break;
}
case FLOAT_LAYOUT: {
floating **float1ptrptr = (floating **)(child1intptr);
floating **float2ptrptr = (floating **)(child2intptr);
bool cmp = hook_FLOAT_trueeq(*float1ptrptr, *float2ptrptr);
if (!cmp) {
return false;
}
break;
}
case STRINGBUFFER_LAYOUT: {
abort();
}
case BOOL_LAYOUT: {
bool *bool1ptr = (bool *)(child1intptr);
bool *bool2ptr = (bool *)(child2intptr);
bool cmp = *bool1ptr == *bool2ptr;
if (!cmp) {
return false;
}
break;
}
case SYMBOL_LAYOUT: {
block **child1ptrptr = (block **)(child1intptr);
block **child2ptrptr = (block **)(child2intptr);
bool cmp = hook_KEQUAL_eq(*child1ptrptr, *child2ptrptr);
if (!cmp) {
return false;
}
break;
}
case VARIABLE_LAYOUT: {
block **var1ptrptr = (block **)(child1intptr);
block **var2ptrptr = (block **)(child2intptr);
bool cmp = hook_STRING_eq(
(string *)*var1ptrptr, (string *)*var2ptrptr);
if (!cmp) {
return false;
}
break;
}
default: abort();
}
}
return true;
}
} else { // arg1hdrcanon != arg2hdrcanon
return false;
}
}
} else { // arg1lb != arg2lb
// Between arg1 and arg2, one is a constant and one is a block.
return false;
}
}

// We arbitrarily impose the following ordering betwene different types of
// blocks:
// - Constants < Blocks.
// - Symbols < Strings.
// - Symbols with different tags are ordered based on their tags.
// - Symbols with same tags are ordered be lexicographically comparing their
// childen.
bool hook_KEQUAL_lt(block *arg1, block *arg2) {
uint64_t arg1intptr = (uint64_t)arg1;
uint64_t arg2intptr = (uint64_t)arg2;
bool isconstant1 = is_leaf_block(arg1intptr);
bool isconstant2 = is_leaf_block(arg2intptr);
if (isconstant1 != isconstant2) {
// Between arg1 and arg2, one is a constant and one is not.
return isconstant1;
} else if (isconstant1) {
// Both arg1 and arg2 are constants.
return arg1intptr < arg2intptr;
} else {
// Both arg1 and arg2 are blocks.
uint16_t arg1layout = layout(arg1);
uint16_t arg2layout = layout(arg2);
if (arg1layout == 0 && arg2layout == 0) {
// Both arg1 and arg2 are strings.
return hook_STRING_lt((string *)arg1, (string *)arg2);
} else if (arg1layout == 0 || arg2layout == 0) {
// One of arg1, arg2 is a string, the other is a symbol.
return arg2layout == 0;
} else {
// Both arg1 and arg2 are symbols.
uint32_t arg1tag = tag(arg1);
uint32_t arg2tag = tag(arg2);
if (arg1tag != arg2tag) {
return arg1tag < arg2tag;
} else {
assert(arg1layout == arg2layout);
layout *layoutPtr = getLayoutData(arg1layout);
uint8_t length = layoutPtr->nargs;
for (uint8_t i = 0; i < length; i++) {
uint64_t offset = layoutPtr->args[i].offset;
uint16_t cat = layoutPtr->args[i].cat;
switch (cat) {
case MAP_LAYOUT: {
abort(); // Implement when needed.
}
case LIST_LAYOUT: {
abort(); // Implement when needed.
}
case SET_LAYOUT: {
abort(); // Implement when needed.
}
case INT_LAYOUT: {
mpz_ptr *int1ptrptr = (mpz_ptr *)(arg1intptr + offset);
mpz_ptr *int2ptrptr = (mpz_ptr *)(arg2intptr + offset);
int cmp = mpz_cmp(*int1ptrptr, *int2ptrptr);
if (cmp != 0) {
return cmp < 0;
}
break;
}
case FLOAT_LAYOUT: {
abort(); // Implement when needed.
}
case STRINGBUFFER_LAYOUT: {
abort(); // Implement when needed.
}
case BOOL_LAYOUT: {
abort(); // Implement when needed.
}
case SYMBOL_LAYOUT: {
abort(); // Implement when needed.
}
case VARIABLE_LAYOUT: {
abort(); // Implement when needed.
}
default: abort();
}
}
return false;
}
}
}
}

bool hook_KEQUAL_ne(block *arg1, block *arg2) {
return !hook_KEQUAL_eq(arg1, arg2);
}

bool hook_BOOL_eq(bool arg1, bool arg2) {
return arg1 == arg2;
}
}
Loading