Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
H
hpvm-deepcopy
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
llvm
hpvm-deepcopy
Commits
550cebaa
Commit
550cebaa
authored
2 years ago
by
git_unspecified
Browse files
Options
Downloads
Patches
Plain Diff
Provide trivial copy by default
parent
f9cd4127
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/guided_dc.cc
+102
-135
102 additions, 135 deletions
src/guided_dc.cc
with
102 additions
and
135 deletions
src/guided_dc.cc
+
102
−
135
View file @
550cebaa
#include
<argp.h>
#include
<argp.h>
#include
<assert.h>
#include
<math.h>
#include
<stdio.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<stdlib.h>
#include
<iostream>
#include
<assert.h>
#include
<functional>
#include
<string.h>
#include
<string.h>
#include
<math.h>
#include
<functional>
#include
<iostream>
#include
<typeinfo>
#include
<typeinfo>
#include
<vector>
#include
<unordered_map>
#include
<unordered_map>
#include
<vector>
#include
"./pinnedVector/pinnedVector/PinnedVector.h"
#include
"./pinnedVector/pinnedVector/PinnedVector.h"
#define USE_HPVM
#define USE_HPVM
...
@@ -28,102 +29,76 @@
...
@@ -28,102 +29,76 @@
using
byte
=
char
;
using
byte
=
char
;
// In a separate file ----------------------
// In a separate file ----------------------
static
std
::
unordered_map
<
void
*
,
std
::
pair
<
const
std
::
type_info
*
,
size_t
>>
static
std
::
unordered_map
<
void
*
,
std
::
pair
<
const
std
::
type_info
*
,
size_t
>>
hpvm_allocation_record
;
hpvm_allocation_record
;
// Lib header provides ---------------------
// Lib header provides ---------------------
extern
std
::
unordered_map
<
void
*
,
std
::
pair
<
const
std
::
type_info
*
,
size_t
>>
extern
std
::
unordered_map
<
void
*
,
std
::
pair
<
const
std
::
type_info
*
,
size_t
>>
hpvm_allocation_record
;
hpvm_allocation_record
;
bool
is_allocated_memory
(
void
*
ptr
)
{
bool
is_allocated_memory
(
void
*
ptr
)
{
return
hpvm_allocation_record
.
count
(
ptr
);
return
hpvm_allocation_record
.
count
(
ptr
);
}
}
size_t
allocation_size
(
void
*
ptr
)
{
size_t
allocation_size
(
void
*
ptr
)
{
if
(
is_allocated_memory
(
ptr
))
if
(
is_allocated_memory
(
ptr
))
return
hpvm_allocation_record
[
ptr
].
second
;
return
hpvm_allocation_record
[
ptr
].
second
;
return
0
;
return
0
;
}
}
template
<
class
T
,
class
...
Args
>
T
*
hpvm_new
(
Args
...
args
)
{
template
<
class
T
,
class
...
Args
>
T
*
obj
=
new
T
(
args
...);
T
*
hpvm_new
(
Args
...
args
)
{
T
*
obj
=
new
T
(
args
...);
hpvm_allocation_record
[
obj
]
=
{
&
typeid
(
T
),
sizeof
(
T
)};
hpvm_allocation_record
[
obj
]
=
{
&
typeid
(
T
),
sizeof
(
T
)};
return
obj
;
return
obj
;
}
}
template
<
class
T
,
class
...
Args
>
void
hpvm_delete
(
T
*
obj
)
{
template
<
class
T
,
class
...
Args
>
void
hpvm_delete
(
T
*
obj
)
{
hpvm_allocation_record
.
erase
(
obj
);
hpvm_allocation_record
.
erase
(
obj
);
delete
obj
;
delete
obj
;
}
}
// Hpvm Buf layout:
// Hpvm Buf layout:
// [header, pointer_recover_list(size_t[]), obj_buf]
// [header, pointer_recover_list(size_t[]), obj_buf]
template
<
typename
T
>
class
HpvmBufHeader
{
template
<
typename
T
>
public:
class
HpvmBufHeader
{
public:
size_t
pointer_recover_list_size
;
size_t
pointer_recover_list_size
;
size_t
obj_size
;
size_t
obj_size
;
byte
buf
[];
byte
buf
[];
void
*
get_obj_start
()
{
void
*
get_obj_start
()
{
return
buf
+
pointer_recover_list_size
*
sizeof
(
size_t
);
return
buf
+
pointer_recover_list_size
*
sizeof
(
size_t
);
}
}
size_t
*
get_pointer_list_start
()
{
return
(
size_t
*
)
buf
;
}
size_t
*
get_pointer_list_start
()
{
return
(
size_t
*
)
buf
;
}
size_t
*
get_pointer_at
(
size_t
offset
)
{
size_t
*
get_pointer_at
(
size_t
offset
)
{
size_t
*
sub_ptr
=
(
size_t
*
)((
char
*
)
get_obj_start
()
+
offset
);
size_t
*
sub_ptr
=
(
size_t
*
)((
char
*
)
get_obj_start
()
+
offset
);
return
sub_ptr
;
return
sub_ptr
;
}
}
void
to_relative_pointer
(
void
*
base
)
{
void
to_relative_pointer
(
void
*
base
)
{
for
(
int
i
=
0
;
i
<
pointer_recover_list_size
;
i
++
)
{
for
(
int
i
=
0
;
i
<
pointer_recover_list_size
;
i
++
)
{
size_t
pointer_offset
=
get_pointer_list_start
()[
i
];
size_t
pointer_offset
=
get_pointer_list_start
()[
i
];
size_t
*
sub_ptr
=
get_pointer_at
(
pointer_offset
);
size_t
*
sub_ptr
=
get_pointer_at
(
pointer_offset
);
#ifndef USE_HPVM
#ifndef USE_HPVM
std
::
cout
<<
"To relative: "
<<
(
void
*
)
sub_ptr
[
0
];
std
::
cout
<<
"To relative: "
<<
(
void
*
)
sub_ptr
[
0
];
#endif
#endif
sub_ptr
[
0
]
-=
(
size_t
)
base
;
sub_ptr
[
0
]
-=
(
size_t
)
base
;
#ifndef USE_HPVM
#ifndef USE_HPVM
std
::
cout
<<
" -> "
<<
(
void
*
)
sub_ptr
[
0
]
<<
"
\n
"
;
std
::
cout
<<
" -> "
<<
(
void
*
)
sub_ptr
[
0
]
<<
"
\n
"
;
#endif
#endif
}
}
}
}
void
to_absolute_pointer
(
void
*
base
,
bool
device
=
false
)
{
void
to_absolute_pointer
(
void
*
base
,
bool
device
=
false
)
{
// to_relative_pointer((void *)(-(size_t)base));
to_relative_pointer
((
void
*
)(
-
(
size_t
)
base
));
if
(
device
)
{
// FAULT: this will fault
//((char *)(this->get_obj_start()))[0xfffffff] = 1;
}
// assert pointer_recover_list_size > 0
if
(
pointer_recover_list_size
<=
0
)
((
char
*
)(
this
->
get_obj_start
()))[
0xfffffff
]
=
1
;
for
(
int
i
=
0
;
i
<
pointer_recover_list_size
;
i
++
)
if
(
device
)
{
// FAULT: this will not fault
((
char
*
)(
this
->
get_obj_start
()))[
0xfffffff
]
=
1
;
}
for
(
int
i
=
0
;
i
<
pointer_recover_list_size
;
i
++
)
{
if
(
device
)
{
// FAULT: this will not fault
((
char
*
)(
this
->
get_obj_start
()))[
0xfffffff
]
=
1
;
}
size_t
pointer_offset
=
get_pointer_list_start
()[
i
];
size_t
*
sub_ptr
=
get_pointer_at
(
pointer_offset
);
#ifndef USE_HPVM
std
::
cout
<<
"To relative: "
<<
(
void
*
)
sub_ptr
[
0
];
#endif
sub_ptr
[
0
]
+=
(
size_t
)
base
;
#ifndef USE_HPVM
std
::
cout
<<
" -> "
<<
(
void
*
)
sub_ptr
[
0
]
<<
"
\n
"
;
#endif
}
}
}
size_t
total_size
()
{
size_t
total_size
()
{
return
sizeof
(
*
this
)
+
pointer_recover_list_size
*
sizeof
(
size_t
)
+
return
sizeof
(
*
this
)
+
pointer_recover_list_size
*
sizeof
(
size_t
)
+
obj_size
;
obj_size
;
}
}
};
};
template
<
typename
T
>
class
HpvmBuf
{
template
<
typename
T
>
public:
class
HpvmBuf
{
HpvmBufHeader
<
T
>
*
buf
=
nullptr
;
public:
HpvmBufHeader
<
T
>*
buf
=
nullptr
;
std
::
vector
<
size_t
>
rel_pointer_list
;
std
::
vector
<
size_t
>
rel_pointer_list
;
PinnedVector
<
byte
>
obj_data
;
PinnedVector
<
byte
>
obj_data
;
...
@@ -132,12 +107,11 @@ public:
...
@@ -132,12 +107,11 @@ public:
obj_data
.
reserve
(
1
);
obj_data
.
reserve
(
1
);
}
}
HpvmBufHeader
<
T
>
*
formulate_device_buffer
()
{
HpvmBufHeader
<
T
>*
formulate_device_buffer
()
{
if
(
buf
)
if
(
buf
)
free
(
buf
);
free
(
buf
);
size_t
buf_size
=
sizeof
(
*
buf
)
+
rel_pointer_list
.
size
()
*
sizeof
(
size_t
)
+
size_t
buf_size
=
sizeof
(
*
buf
)
+
rel_pointer_list
.
size
()
*
sizeof
(
size_t
)
+
obj_data
.
size
();
obj_data
.
size
();
buf
=
(
HpvmBufHeader
<
T
>
*
)
calloc
(
buf_size
,
1
);
buf
=
(
HpvmBufHeader
<
T
>*
)
calloc
(
buf_size
,
1
);
buf
->
pointer_recover_list_size
=
rel_pointer_list
.
size
();
buf
->
pointer_recover_list_size
=
rel_pointer_list
.
size
();
buf
->
obj_size
=
obj_data
.
size
();
buf
->
obj_size
=
obj_data
.
size
();
...
@@ -146,36 +120,36 @@ public:
...
@@ -146,36 +120,36 @@ public:
buf
->
pointer_recover_list_size
*
sizeof
(
size_t
));
buf
->
pointer_recover_list_size
*
sizeof
(
size_t
));
memcpy
(
buf
->
get_obj_start
(),
obj_data
.
data
(),
buf
->
obj_size
);
memcpy
(
buf
->
get_obj_start
(),
obj_data
.
data
(),
buf
->
obj_size
);
std
::
cout
<<
"We will have pointers at offsets: "
;
std
::
cout
<<
"We will have pointers at offsets: "
;
for
(
auto
i
:
rel_pointer_list
)
for
(
auto
i
:
rel_pointer_list
)
std
::
cout
<<
(
void
*
)
i
<<
","
;
std
::
cout
<<
(
void
*
)
i
<<
","
;
std
::
cout
<<
"
\n
"
;
std
::
cout
<<
"
\n
"
;
buf
->
to_relative_pointer
(
obj_data
.
data
());
buf
->
to_relative_pointer
(
obj_data
.
data
());
return
buf
;
return
buf
;
}
}
T
*
recover_host_accessible_obj
()
{
T
*
recover_host_accessible_obj
()
{
buf
->
to_absolute_pointer
(
buf
->
get_obj_start
());
buf
->
to_absolute_pointer
(
buf
->
get_obj_start
());
return
(
T
*
)
buf
->
get_obj_start
();
return
(
T
*
)
buf
->
get_obj_start
();
}
}
template
<
class
AllocType
=
void
>
AllocType
*
allocate
(
size_t
size
)
{
template
<
class
AllocType
=
void
>
if
(
size
==
0
)
AllocType
*
allocate
(
size_t
size
)
{
return
nullptr
;
if
(
size
==
0
)
return
nullptr
;
size_t
old_size
=
obj_data
.
size
();
size_t
old_size
=
obj_data
.
size
();
obj_data
.
resize
(
obj_data
.
size
()
+
size
);
obj_data
.
resize
(
obj_data
.
size
()
+
size
);
std
::
cout
<<
"Allocate up to:"
<<
obj_data
.
size
()
<<
" bytes"
<<
std
::
endl
;
std
::
cout
<<
"Allocate up to:"
<<
obj_data
.
size
()
<<
" bytes"
<<
std
::
endl
;
return
(
AllocType
*
)(
obj_data
.
data
()
+
old_size
);
return
(
AllocType
*
)(
obj_data
.
data
()
+
old_size
);
}
}
void
register_pointer_in_buf
(
void
*
ptr_addr_in_buf
)
{
void
register_pointer_in_buf
(
void
*
ptr_addr_in_buf
)
{
rel_pointer_list
.
push_back
((
size_t
)(
ptr_addr_in_buf
)
-
rel_pointer_list
.
push_back
((
size_t
)(
ptr_addr_in_buf
)
-
(
size_t
)
obj_data
.
data
());
(
size_t
)
obj_data
.
data
());
}
}
};
};
// Main user entry to snapshot an object into a buffer
// Main user entry to snapshot an object into a buffer
template
<
class
T
>
HpvmBuf
<
T
>
hpvm_snapshot
(
T
*
original_obj
)
{
template
<
class
T
>
std
::
cout
<<
"Snapshot: "
<<
(
void
*
)
original_obj
<<
std
::
endl
;
HpvmBuf
<
T
>
hpvm_snapshot
(
T
*
original_obj
)
{
std
::
cout
<<
"Snapshot: "
<<
(
void
*
)
original_obj
<<
std
::
endl
;
HpvmBuf
<
T
>
buf
;
HpvmBuf
<
T
>
buf
;
hpvm_snapshot_internal
(
buf
,
original_obj
);
hpvm_snapshot_internal
(
buf
,
original_obj
);
std
::
cout
<<
"Snapshot Done
\n
"
;
std
::
cout
<<
"Snapshot Done
\n
"
;
...
@@ -183,23 +157,36 @@ template <class T> HpvmBuf<T> hpvm_snapshot(T *original_obj) {
...
@@ -183,23 +157,36 @@ template <class T> HpvmBuf<T> hpvm_snapshot(T *original_obj) {
return
buf
;
return
buf
;
}
}
// Allocated space at end of buffer and do trivial copy
template
<
class
T
,
class
Buf
>
T
*
snapshot_trivial
(
Buf
&
buf
,
T
*
src
)
{
auto
*
dst
=
buf
.
template
allocate
<
T
>(
sizeof
(
T
));
memcpy
(
dst
,
src
,
sizeof
(
T
));
return
dst
;
}
// User can implement this specialization for deep copy
template
<
class
Buf
,
class
T
>
template
<
class
Buf
,
class
T
>
extern
T
*
hpvm_snapshot_internal
(
Buf
&
buf
,
T
*
original_obj
);
extern
void
hpvm_snapshot_custom
(
Buf
&
buf
,
T
*
dst_obj
,
T
*
original_obj
)
{}
// Snapshot function used internally
template
<
class
Buf
,
class
T
>
extern
T
*
hpvm_snapshot_internal
(
Buf
&
buf
,
T
*
original_obj
)
{
auto
*
dst
=
snapshot_trivial
(
buf
,
original_obj
);
hpvm_snapshot_custom
(
buf
,
dst
,
original_obj
);
return
dst
;
}
// Snapshot an (array of) pointer(s)
template
<
class
T
,
class
Buf
>
template
<
class
T
,
class
Buf
>
void
snapshot_pointer
(
Buf
&
buf
,
T
*&
dst_ptr
,
T
*
src_ptr
)
{
void
*
snapshot_pointer
(
Buf
&
buf
,
T
*
src_ptr
)
{
if
(
is_allocated_memory
(
src_ptr
))
{
if
(
is_allocated_memory
(
src_ptr
))
{
dst_ptr
=
hpvm_snapshot_internal
(
buf
,
src_ptr
);
auto
*
dst
=
hpvm_snapshot_internal
(
buf
,
src_ptr
);
// TODO: ptr to array larger than 1 elem
buf
.
register_pointer_in_buf
(
&
dst_ptr
);
buf
.
register_pointer_in_buf
(
&
dst_ptr
);
}
else
{
return
dst
;
dst_ptr
=
nullptr
;
}
else
}
return
nullptr
;
}
template
<
class
T
,
class
Buf
>
void
snapshot_trivial
(
Buf
&
buf
,
T
*&
dst
,
T
*
src
)
{
dst
=
buf
.
template
allocate
<
T
>(
sizeof
(
T
));
memcpy
(
dst
,
src
,
sizeof
(
T
));
}
}
// Library function
// Library function
...
@@ -208,9 +195,9 @@ template <class T, class Buf> void snapshot_trivial(Buf &buf, T *&dst, T *src) {
...
@@ -208,9 +195,9 @@ template <class T, class Buf> void snapshot_trivial(Buf &buf, T *&dst, T *src) {
// User code
// User code
// A linked list:
// A linked list:
class
LNode
{
class
LNode
{
public:
public:
int
val
;
int
val
;
LNode
*
next
=
nullptr
;
LNode
*
next
=
nullptr
;
inline
LNode
(
int
v
)
{
val
=
v
;
}
inline
LNode
(
int
v
)
{
val
=
v
;
}
void
print
()
{
void
print
()
{
std
::
cout
<<
"[Node "
<<
val
<<
"] -> "
;
std
::
cout
<<
"[Node "
<<
val
<<
"] -> "
;
...
@@ -220,7 +207,7 @@ public:
...
@@ -220,7 +207,7 @@ public:
std
::
cout
<<
"null"
std
::
cout
<<
"null"
<<
"
\n
"
;
<<
"
\n
"
;
}
}
static
LNode
*
create_nodes
(
std
::
initializer_list
<
int
>
vs
)
{
static
LNode
*
create_nodes
(
std
::
initializer_list
<
int
>
vs
)
{
LNode
*
root
=
nullptr
,
*
curr
=
nullptr
;
LNode
*
root
=
nullptr
,
*
curr
=
nullptr
;
for
(
auto
v
:
vs
)
{
for
(
auto
v
:
vs
)
{
if
(
!
root
)
if
(
!
root
)
...
@@ -231,44 +218,26 @@ public:
...
@@ -231,44 +218,26 @@ public:
return
root
;
return
root
;
}
}
};
};
class
X
{
public:
int
k
;
void
test
(
void
*
addr
)
{
for
(
int
i
=
0
;
i
<
k
;
i
++
)
// FAULT: this will not fault
((
char
*
)(
addr
))[
0xfffffff
]
=
1
;
}
};
#ifdef USE_HPVM
#ifdef USE_HPVM
void
stencil
(
HpvmBufHeader
<
LNode
>
*
buf_header
,
size_t
header_size
)
{
void
stencil
(
HpvmBufHeader
<
LNode
>*
buf_header
,
size_t
header_size
)
{
void
*
Section
=
__hetero_section_begin
();
void
*
Section
=
__hetero_section_begin
();
void
*
Wrapper
=
__hetero_task_begin
(
1
,
(
void
*
)
buf_header
,
header_size
,
1
,
void
*
Wrapper
=
__hetero_task_begin
(
1
,
(
void
*
)
buf_header
,
header_size
,
1
,
(
void
*
)
buf_header
,
header_size
);
(
void
*
)
buf_header
,
header_size
);
__hpvm__hint
(
hpvm
::
GPU_TARGET
);
__hpvm__hint
(
hpvm
::
GPU_TARGET
);
auto
*
root
=
(
LNode
*
)(
buf_header
->
get_obj_start
());
auto
*
root
=
(
LNode
*
)(
buf_header
->
get_obj_start
());
buf_header
->
to_absolute_pointer
(
buf_header
->
get_obj_start
(),
true
);
buf_header
->
to_absolute_pointer
(
buf_header
->
get_obj_start
(),
true
);
// X{(int)buf_header->pointer_recover_list_size}.test(buf_header->get_obj_start());
// root->val = (size_t)root->next;
// root->val = buf_header->get_pointer_list_start()[0];
// size_t ptr_ofs1 = buf_header->get_pointer_list_start()[0];
// root->val = buf_header->get_pointer_at(ptr_ofs1)[0];
// (size_t)buf_header->get_obj_start();
// LNode *next = (LNode *)((char *)root + sizeof(LNode));
// next->val = 200;
//
root->next->val = 100;
root
->
next
->
val
=
100
;
// while (root) {
while
(
root
)
{
// root->val += 1;
root
->
val
+=
1
;
// root = root->next;
// root->val = (size_t)root->next;
// }
root
=
root
->
next
;
}
buf_header
->
to_relative_pointer
(
buf_header
->
get_obj_start
());
buf_header
->
to_relative_pointer
(
buf_header
->
get_obj_start
());
__hetero_task_end
(
Wrapper
);
__hetero_task_end
(
Wrapper
);
...
@@ -276,9 +245,8 @@ void stencil(HpvmBufHeader<LNode> *buf_header, size_t header_size) {
...
@@ -276,9 +245,8 @@ void stencil(HpvmBufHeader<LNode> *buf_header, size_t header_size) {
}
}
#endif
#endif
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
LNode
*
host_obj
=
LNode
::
create_nodes
({
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
});
LNode
*
host_obj
=
LNode
::
create_nodes
({
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
});
std
::
cout
<<
"Before kernel:
\n
"
;
std
::
cout
<<
"Before kernel:
\n
"
;
host_obj
->
print
();
host_obj
->
print
();
...
@@ -287,17 +255,20 @@ int main(int argc, char *argv[]) {
...
@@ -287,17 +255,20 @@ int main(int argc, char *argv[]) {
#ifdef USE_HPVM
#ifdef USE_HPVM
std
::
cout
<<
"Kernel launch!"
<<
std
::
endl
;
std
::
cout
<<
"Kernel launch!"
<<
std
::
endl
;
void
*
DFG
=
__hetero_launch
((
void
*
)
stencil
,
1
,
host_buf
.
buf
,
buf_size
,
1
,
void
*
DFG
=
__hetero_launch
((
void
*
)
stencil
,
1
,
host_buf
.
buf
,
buf_size
,
1
,
host_buf
.
buf
,
buf_size
);
host_buf
.
buf
,
buf_size
);
__hetero_wait
(
DFG
);
__hetero_wait
(
DFG
);
#else
#else
auto
*
buf_header
=
host_buf
.
buf
;
auto
*
buf_header
=
host_buf
.
buf
;
host_buf
.
buf
->
to_absolute_pointer
(
host_buf
.
buf
->
get_obj_start
());
host_buf
.
buf
->
to_absolute_pointer
(
buf_header
->
get_obj_start
());
LNode
*
root
=
(
LNode
*
)
buf_header
->
get_obj_start
();
LNode
*
root
=
(
LNode
*
)
buf_header
->
get_obj_start
();
size_t
ptr_ofs1
=
buf_header
->
get_pointer_list_start
()[
0
];
while
(
root
)
{
root
->
val
=
buf_header
->
get_pointer_at
(
ptr_ofs1
)[
0
];
root
->
val
+=
1
;
// root->val = (size_t)root->next;
root
=
root
->
next
;
}
host_buf
.
buf
->
to_relative_pointer
(
host_buf
.
buf
->
get_obj_start
());
host_buf
.
buf
->
to_relative_pointer
(
host_buf
.
buf
->
get_obj_start
());
#endif
#endif
...
@@ -310,14 +281,10 @@ int main(int argc, char *argv[]) {
...
@@ -310,14 +281,10 @@ int main(int argc, char *argv[]) {
// User code end---------------------
// User code end---------------------
// HPVM Codegen generates:
// HPVM Codegen generates:
template
<
>
template
<
>
LNode
*
hpvm_snapshot_internal
<
HpvmBuf
<
LNode
>
,
LNode
>
(
HpvmBuf
<
LNode
>
&
buf
,
void
hpvm_snapshot_custom
<
HpvmBuf
<
LNode
>
,
LNode
>
(
HpvmBuf
<
LNode
>&
buf
,
LNode
*
original_obj
)
{
LNode
*
dst_obj
,
LNode
*
new_obj
=
nullptr
;
LNode
*
original_obj
)
{
// recursive allocation & copies
// recursive allocation & copies
snapshot_trivial
(
buf
,
new_obj
,
original_obj
);
dst_obj
->
next
=
snapshot_pointer
(
buf
,
original_obj
->
next
);
snapshot_pointer
(
buf
,
new_obj
->
next
,
original_obj
->
next
);
return
new_obj
;
}
}
// HPVM Codegen end ------------
// HPVM Codegen end ------------
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment