Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
b2a3fb22
Commit
b2a3fb22
authored
Aug 19, 2016
by
Marius Wachtler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
misc small memory size reductions
parent
7c1ee4cc
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
74 additions
and
61 deletions
+74
-61
src/asm_writing/icinfo.cpp
src/asm_writing/icinfo.cpp
+22
-11
src/asm_writing/icinfo.h
src/asm_writing/icinfo.h
+8
-6
src/codegen/ast_interpreter.cpp
src/codegen/ast_interpreter.cpp
+7
-7
src/codegen/codegen.cpp
src/codegen/codegen.cpp
+2
-2
src/codegen/irgen/hooks.cpp
src/codegen/irgen/hooks.cpp
+18
-18
src/codegen/irgen/irgenerator.cpp
src/codegen/irgen/irgenerator.cpp
+6
-7
src/codegen/irgen/irgenerator.h
src/codegen/irgen/irgenerator.h
+1
-1
src/core/types.h
src/core/types.h
+9
-8
src/runtime/util.cpp
src/runtime/util.cpp
+1
-1
No files found.
src/asm_writing/icinfo.cpp
View file @
b2a3fb22
...
...
@@ -252,15 +252,19 @@ void ICSlotRewrite::addDependenceOn(ICInvalidator& invalidator) {
int
ICInfo
::
calculateSuggestedSize
()
{
// if we never rewrote this IC just return the whole IC size for now
if
(
!
times_rewritten
)
return
slots
[
0
].
size
;
return
slots
.
begin
()
->
size
;
int
additional_space_per_slot
=
50
;
// if there are less rewrites than slots we can give a very accurate estimate
if
(
times_rewritten
<
slots
.
size
())
{
// add up the sizes of all used slots
int
size
=
0
;
for
(
int
i
=
0
;
i
<
times_rewritten
;
++
i
)
{
size
+=
slots
[
i
].
size
+
additional_space_per_slot
;
int
i
=
0
;
for
(
auto
&&
slot
:
slots
)
{
if
(
i
>=
times_rewritten
)
break
;
size
+=
slot
.
size
+
additional_space_per_slot
;
++
i
;
}
return
size
;
}
...
...
@@ -286,18 +290,23 @@ ICSlotInfo* ICInfo::pickEntryForRewrite(const char* debug_name) {
int
num_slots
=
slots
.
size
();
int
fallback_to_in_use_slot
=
-
1
;
llvm
::
SmallVector
<
ICSlotInfo
*
,
8
>
slots_vec
;
for
(
auto
&&
slot
:
slots
)
{
slots_vec
.
push_back
(
&
slot
);
}
// we prefer to use a unused slot and if non is available we will fallback to a slot which is in use (but no one is
// inside)
for
(
int
_i
=
0
;
_i
<
num_slots
;
_i
++
)
{
int
i
=
(
_i
+
next_slot_to_try
)
%
num_slots
;
ICSlotInfo
&
sinfo
=
slots
[
i
];
assert
(
sinfo
.
num_inside
>=
0
);
ICSlotInfo
*
sinfo
=
slots_vec
[
i
];
assert
(
sinfo
->
num_inside
>=
0
);
if
(
sinfo
.
num_inside
||
sinfo
.
size
==
0
)
if
(
sinfo
->
num_inside
||
sinfo
->
size
==
0
)
continue
;
if
(
sinfo
.
used
)
{
if
(
sinfo
->
used
)
{
if
(
fallback_to_in_use_slot
==
-
1
)
fallback_to_in_use_slot
=
i
;
continue
;
...
...
@@ -308,7 +317,7 @@ ICSlotInfo* ICInfo::pickEntryForRewrite(const char* debug_name) {
}
next_slot_to_try
=
i
;
return
&
sinfo
;
return
sinfo
;
}
if
(
fallback_to_in_use_slot
!=
-
1
)
{
...
...
@@ -317,7 +326,7 @@ ICSlotInfo* ICInfo::pickEntryForRewrite(const char* debug_name) {
}
next_slot_to_try
=
fallback_to_in_use_slot
;
return
&
slots
[
fallback_to_in_use_slot
];
return
slots_vec
[
fallback_to_in_use_slot
];
}
if
(
VERBOSITY
()
>=
4
)
...
...
@@ -447,11 +456,13 @@ void ICInfo::invalidate(ICSlotInfo* icentry) {
llvm
::
sys
::
Memory
::
InvalidateInstructionCache
(
start
,
icentry
->
size
);
for
(
int
i
=
0
;
i
<
slots
.
size
();
++
i
)
{
if
(
&
slots
[
i
]
==
icentry
)
{
int
i
=
0
;
for
(
auto
&&
slot
:
slots
)
{
if
(
&
slot
==
icentry
)
{
next_slot_to_try
=
i
;
break
;
}
++
i
;
}
icentry
->
used
=
false
;
...
...
src/asm_writing/icinfo.h
View file @
b2a3fb22
...
...
@@ -15,12 +15,13 @@
#ifndef PYSTON_ASMWRITING_ICINFO_H
#define PYSTON_ASMWRITING_ICINFO_H
#include <
deque
>
#include <
list
>
#include <memory>
#include <unordered_set>
#include <vector>
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/IR/CallingConv.h"
#include "asm_writing/assembler.h"
...
...
@@ -62,15 +63,16 @@ public:
ICInfo
*
ic
;
uint8_t
*
start_addr
;
std
::
vector
<
void
*>
gc_references
;
std
::
vector
<
DecrefInfo
>
decref_infos
;
llvm
::
TinyPtrVector
<
ICInvalidator
*>
invalidators
;
// ICInvalidators that reference this slotinfo
int
num_inside
;
// the number of stack frames that are currently inside this slot will also get increased during a
// rewrite
int
size
;
bool
used
;
// if this slot is empty or got invalidated
std
::
vector
<
void
*>
gc_references
;
std
::
vector
<
DecrefInfo
>
decref_infos
;
std
::
vector
<
ICInvalidator
*>
invalidators
;
// ICInvalidators that reference this slotinfo
void
clear
(
bool
should_invalidate
=
true
);
};
...
...
@@ -79,7 +81,7 @@ typedef BitSet<16> LiveOutSet;
class
ICSlotRewrite
;
class
ICInfo
{
private:
std
::
deque
<
ICSlotInfo
>
slots
;
std
::
list
<
ICSlotInfo
>
slots
;
// For now, just use a round-robin eviction policy.
// This is probably a bunch worse than LRU, but it's also
// probably a bunch better than the "always evict slot #0" policy
...
...
src/codegen/ast_interpreter.cpp
View file @
b2a3fb22
...
...
@@ -74,7 +74,7 @@ public:
static
Box
*
executeInner
(
ASTInterpreter
&
interpreter
,
CFGBlock
*
start_block
,
AST_stmt
*
start_at
);
private:
Value
createFunction
(
AST
*
node
,
AST_arguments
*
args
,
const
std
::
vector
<
AST_stmt
*>&
body
);
Value
createFunction
(
AST
*
node
,
AST_arguments
*
args
);
Value
doBinOp
(
AST_expr
*
node
,
Value
left
,
Value
right
,
int
op
,
BinExpType
exp_type
);
void
doStore
(
AST_expr
*
node
,
STOLEN
(
Value
)
value
);
void
doStore
(
AST_Name
*
name
,
STOLEN
(
Value
)
value
);
...
...
@@ -1131,8 +1131,8 @@ Value ASTInterpreter::visit_return(AST_Return* node) {
return
s
;
}
Value
ASTInterpreter
::
createFunction
(
AST
*
node
,
AST_arguments
*
args
,
const
std
::
vector
<
AST_stmt
*>&
body
)
{
FunctionMetadata
*
md
=
wrapFunction
(
node
,
args
,
body
,
source_info
);
Value
ASTInterpreter
::
createFunction
(
AST
*
node
,
AST_arguments
*
args
)
{
FunctionMetadata
*
md
=
wrapFunction
(
node
,
args
,
source_info
);
std
::
vector
<
Box
*>
defaults
;
llvm
::
SmallVector
<
RewriterVar
*
,
4
>
defaults_vars
;
...
...
@@ -1232,7 +1232,7 @@ Value ASTInterpreter::visit_makeFunction(AST_MakeFunction* mkfn) {
for
(
AST_expr
*
d
:
node
->
decorator_list
)
decorators
.
push_back
(
visit_expr
(
d
));
Value
func
=
createFunction
(
node
,
args
,
node
->
body
);
Value
func
=
createFunction
(
node
,
args
);
for
(
int
i
=
decorators
.
size
()
-
1
;
i
>=
0
;
i
--
)
{
func
.
o
=
runtimeCall
(
autoDecref
(
decorators
[
i
].
o
),
ArgPassSpec
(
1
),
autoDecref
(
func
.
o
),
0
,
0
,
0
,
0
);
...
...
@@ -1271,7 +1271,7 @@ Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) {
closure
=
created_closure
;
assert
(
closure
);
}
FunctionMetadata
*
md
=
wrapFunction
(
node
,
nullptr
,
node
->
body
,
source_info
);
FunctionMetadata
*
md
=
wrapFunction
(
node
,
nullptr
,
source_info
);
Box
*
passed_globals
=
NULL
;
if
(
!
getMD
()
->
source
->
scoping
->
areGlobalsFromModule
())
...
...
@@ -1553,7 +1553,7 @@ Value ASTInterpreter::visit_call(AST_Call* node) {
AUTO_DECREF
(
func
.
o
);
std
::
vector
<
Box
*
>
args
;
llvm
::
SmallVector
<
Box
*
,
8
>
args
;
llvm
::
SmallVector
<
RewriterVar
*
,
8
>
args_vars
;
args
.
reserve
(
node
->
args
.
size
());
args_vars
.
reserve
(
node
->
args
.
size
());
...
...
@@ -1586,7 +1586,7 @@ Value ASTInterpreter::visit_call(AST_Call* node) {
args_vars
.
push_back
(
v
);
}
AUTO_DECREF_ARRAY
(
&
args
[
0
]
,
args
.
size
());
AUTO_DECREF_ARRAY
(
args
.
data
()
,
args
.
size
());
ArgPassSpec
argspec
(
node
->
args
.
size
(),
node
->
keywords
.
size
(),
node
->
starargs
,
node
->
kwargs
);
...
...
src/codegen/codegen.cpp
View file @
b2a3fb22
...
...
@@ -87,12 +87,12 @@ void FunctionMetadata::addVersion(CompiledFunction* compiled) {
assert
(
compiled
->
spec
->
arg_types
.
size
()
==
numReceivedArgs
());
versions
.
push_back
(
compiled
);
}
else
{
osr_versions
[
compiled
->
entry_descriptor
]
=
compiled
;
osr_versions
.
emplace_front
(
compiled
->
entry_descriptor
,
compiled
)
;
}
}
SourceInfo
::
SourceInfo
(
BoxedModule
*
m
,
ScopingAnalysis
*
scoping
,
FutureFlags
future_flags
,
AST
*
ast
,
BoxedString
*
fn
)
:
parent_module
(
m
),
scoping
(
scoping
),
scope_info
(
NULL
),
future_flags
(
future_flags
),
ast
(
ast
),
cfg
(
NULL
)
{
:
parent_module
(
m
),
scoping
(
scoping
),
scope_info
(
NULL
),
ast
(
ast
),
cfg
(
NULL
),
future_flags
(
future_flags
)
{
assert
(
fn
);
// TODO: this is a very bad way of handling this:
...
...
src/codegen/irgen/hooks.cpp
View file @
b2a3fb22
...
...
@@ -56,7 +56,7 @@ namespace pyston {
// TODO terrible place for these!
ParamNames
::
ParamNames
(
AST
*
ast
,
InternedStringPool
&
pool
)
:
takes_param_names
(
true
),
vararg_name
(
NULL
),
kwarg_name
(
NULL
)
{
:
vararg_name
(
NULL
),
kwarg_name
(
NULL
),
takes_param_names
(
true
)
{
if
(
ast
->
type
==
AST_TYPE
::
Module
||
ast
->
type
==
AST_TYPE
::
ClassDef
||
ast
->
type
==
AST_TYPE
::
Expression
||
ast
->
type
==
AST_TYPE
::
Suite
)
{
kwarg
=
""
;
...
...
@@ -90,7 +90,7 @@ ParamNames::ParamNames(AST* ast, InternedStringPool& pool)
}
ParamNames
::
ParamNames
(
const
std
::
vector
<
llvm
::
StringRef
>&
args
,
llvm
::
StringRef
vararg
,
llvm
::
StringRef
kwarg
)
:
takes_param_names
(
true
),
vararg_name
(
NULL
),
kwarg_name
(
NULL
)
{
:
vararg_name
(
NULL
),
kwarg_name
(
NULL
),
takes_param_names
(
true
)
{
this
->
args
=
args
;
this
->
vararg
=
vararg
;
this
->
kwarg
=
kwarg
;
...
...
@@ -233,7 +233,7 @@ CompiledFunction* compileFunction(FunctionMetadata* f, FunctionSpecialization* s
BoxedString
*
name
=
source
->
getName
();
ASSERT
(
f
->
versions
.
size
()
<
20
,
"%s %
ld
"
,
name
->
c_str
(),
f
->
versions
.
size
());
ASSERT
(
f
->
versions
.
size
()
<
20
,
"%s %
u
"
,
name
->
c_str
(),
f
->
versions
.
size
());
ExceptionStyle
exception_style
;
if
(
force_exception_style
)
...
...
@@ -669,14 +669,14 @@ void CompiledFunction::speculationFailed() {
}
if
(
!
found
)
{
for
(
auto
it
=
md
->
osr_versions
.
begin
();
it
!=
md
->
osr_versions
.
end
();
++
it
)
{
if
(
it
->
second
==
this
)
{
md
->
osr_versions
.
erase
(
it
);
md
->
osr_versions
.
remove_if
([
&
](
const
std
::
pair
<
const
OSREntryDescriptor
*
,
CompiledFunction
*>&
e
)
{
if
(
e
.
second
==
this
)
{
this
->
dependent_callsites
.
invalidateAll
();
found
=
true
;
break
;
return
true
;
}
}
return
false
;
});
}
if
(
!
found
)
{
...
...
@@ -752,7 +752,7 @@ static CompiledFunction* _doReopt(CompiledFunction* cf, EffortLevel new_effort)
}
}
printf
(
"Couldn't find a version; %
ld
exist:
\n
"
,
versions
.
size
());
printf
(
"Couldn't find a version; %
u
exist:
\n
"
,
versions
.
size
());
for
(
auto
cf
:
versions
)
{
printf
(
"%p
\n
"
,
cf
);
}
...
...
@@ -770,17 +770,17 @@ CompiledFunction* compilePartialFuncInternal(OSRExit* exit) {
FunctionMetadata
*
md
=
exit
->
entry
->
md
;
assert
(
md
);
CompiledFunction
*&
new_cf
=
md
->
osr_versions
[
exit
->
entry
];
if
(
new_cf
==
NULL
)
{
EffortLevel
new_effort
=
EffortLevel
::
MAXIMAL
;
CompiledFunction
*
compiled
=
compileFunction
(
md
,
NULL
,
new_effort
,
exit
->
entry
,
true
,
exit
->
entry
->
exception_style
);
assert
(
compiled
==
new_cf
);
stat_osr_compiles
.
log
();
for
(
auto
&&
osr_functions
:
md
->
osr_versions
)
{
if
(
osr_functions
.
first
==
exit
->
entry
)
return
osr_functions
.
second
;
}
return
new_cf
;
EffortLevel
new_effort
=
EffortLevel
::
MAXIMAL
;
CompiledFunction
*
compiled
=
compileFunction
(
md
,
NULL
,
new_effort
,
exit
->
entry
,
true
,
exit
->
entry
->
exception_style
);
stat_osr_compiles
.
log
();
assert
(
std
::
find
(
md
->
osr_versions
.
begin
(),
md
->
osr_versions
.
end
(),
std
::
make_pair
(
exit
->
entry
,
compiled
))
!=
md
->
osr_versions
.
end
());
return
compiled
;
}
void
*
compilePartialFunc
(
OSRExit
*
exit
)
{
...
...
src/codegen/irgen/irgenerator.cpp
View file @
b2a3fb22
...
...
@@ -1617,7 +1617,7 @@ private:
decorators
.
push_back
(
evalExpr
(
d
,
unw_info
));
}
FunctionMetadata
*
md
=
wrapFunction
(
node
,
nullptr
,
node
->
body
,
irstate
->
getSourceInfo
());
FunctionMetadata
*
md
=
wrapFunction
(
node
,
nullptr
,
irstate
->
getSourceInfo
());
// TODO duplication with _createFunction:
llvm
::
Value
*
this_closure
=
NULL
;
...
...
@@ -1658,9 +1658,8 @@ private:
return
cls
;
}
CompilerVariable
*
_createFunction
(
AST
*
node
,
const
UnwindInfo
&
unw_info
,
AST_arguments
*
args
,
const
std
::
vector
<
AST_stmt
*>&
body
)
{
FunctionMetadata
*
md
=
wrapFunction
(
node
,
args
,
body
,
irstate
->
getSourceInfo
());
CompilerVariable
*
_createFunction
(
AST
*
node
,
const
UnwindInfo
&
unw_info
,
AST_arguments
*
args
)
{
FunctionMetadata
*
md
=
wrapFunction
(
node
,
args
,
irstate
->
getSourceInfo
());
std
::
vector
<
ConcreteCompilerVariable
*>
defaults
;
for
(
auto
d
:
args
->
defaults
)
{
...
...
@@ -1706,7 +1705,7 @@ private:
decorators
.
push_back
(
evalExpr
(
d
,
unw_info
));
}
CompilerVariable
*
func
=
_createFunction
(
node
,
unw_info
,
node
->
args
,
node
->
body
);
CompilerVariable
*
func
=
_createFunction
(
node
,
unw_info
,
node
->
args
);
for
(
int
i
=
decorators
.
size
()
-
1
;
i
>=
0
;
i
--
)
{
func
=
decorators
[
i
]
->
call
(
emitter
,
getOpInfoForNode
(
node
,
unw_info
),
ArgPassSpec
(
1
),
{
func
},
NULL
);
...
...
@@ -3248,10 +3247,10 @@ IRGenerator* createIRGenerator(IRGenState* irstate, std::unordered_map<CFGBlock*
return
new
IRGeneratorImpl
(
irstate
,
entry_blocks
,
myblock
,
types
);
}
FunctionMetadata
*
wrapFunction
(
AST
*
node
,
AST_arguments
*
args
,
const
std
::
vector
<
AST_stmt
*>&
body
,
SourceInfo
*
source
)
{
FunctionMetadata
*
wrapFunction
(
AST
*
node
,
AST_arguments
*
args
,
SourceInfo
*
source
)
{
// Different compilations of the parent scope of a functiondef should lead
// to the same FunctionMetadata* being used:
static
std
::
unordered_m
ap
<
AST
*
,
FunctionMetadata
*>
made
;
static
llvm
::
DenseM
ap
<
AST
*
,
FunctionMetadata
*>
made
;
FunctionMetadata
*&
md
=
made
[
node
];
if
(
md
==
NULL
)
{
...
...
src/codegen/irgen/irgenerator.h
View file @
b2a3fb22
...
...
@@ -205,7 +205,7 @@ IREmitter* createIREmitter(IRGenState* irstate, llvm::BasicBlock*& curblock, IRG
IRGenerator
*
createIRGenerator
(
IRGenState
*
irstate
,
std
::
unordered_map
<
CFGBlock
*
,
llvm
::
BasicBlock
*>&
entry_blocks
,
CFGBlock
*
myblock
,
TypeAnalysis
*
types
);
FunctionMetadata
*
wrapFunction
(
AST
*
node
,
AST_arguments
*
args
,
const
std
::
vector
<
AST_stmt
*>&
body
,
SourceInfo
*
source
);
FunctionMetadata
*
wrapFunction
(
AST
*
node
,
AST_arguments
*
args
,
SourceInfo
*
source
);
std
::
vector
<
BoxedString
*>*
getKeywordNameStorage
(
AST_Call
*
node
);
}
...
...
src/core/types.h
View file @
b2a3fb22
...
...
@@ -19,6 +19,7 @@
// over having them spread randomly in different files, this should probably be split again
// but in a way that makes more sense.
#include <forward_list>
#include <memory>
#include <stddef.h>
#include <vector>
...
...
@@ -26,6 +27,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "Python.h"
#include "core/common.h"
...
...
@@ -217,7 +219,6 @@ static_assert(sizeof(ArgPassSpec) <= sizeof(void*), "ArgPassSpec doesn't fit in
static_assert
(
sizeof
(
ArgPassSpec
)
==
sizeof
(
uint32_t
),
"ArgPassSpec::asInt needs to be updated"
);
struct
ParamNames
{
bool
takes_param_names
;
std
::
vector
<
llvm
::
StringRef
>
args
;
llvm
::
StringRef
vararg
,
kwarg
;
...
...
@@ -227,6 +228,8 @@ struct ParamNames {
std
::
vector
<
AST_Name
*>
arg_names
;
AST_Name
*
vararg_name
,
*
kwarg_name
;
bool
takes_param_names
;
explicit
ParamNames
(
AST
*
ast
,
InternedStringPool
&
pool
);
ParamNames
(
const
std
::
vector
<
llvm
::
StringRef
>&
args
,
llvm
::
StringRef
vararg
,
llvm
::
StringRef
kwarg
);
static
ParamNames
empty
()
{
return
ParamNames
();
}
...
...
@@ -241,7 +244,7 @@ struct ParamNames {
}
private:
ParamNames
()
:
takes_param_names
(
false
),
vararg_name
(
NULL
),
kwarg_name
(
NULL
)
{}
ParamNames
()
:
vararg_name
(
NULL
),
kwarg_name
(
NULL
),
takes_param_names
(
false
)
{}
};
// Similar to ArgPassSpec, this struct is how functions specify what their parameter signature is.
...
...
@@ -406,14 +409,15 @@ class LivenessAnalysis;
class
SourceInfo
{
private:
BoxedString
*
fn
;
// equivalent of code.co_filename
std
::
unique_ptr
<
LivenessAnalysis
>
liveness_info
;
public:
BoxedModule
*
parent_module
;
ScopingAnalysis
*
scoping
;
ScopeInfo
*
scope_info
;
FutureFlags
future_flags
;
AST
*
ast
;
CFG
*
cfg
;
FutureFlags
future_flags
;
bool
is_generator
;
InternedStringPool
&
getInternedStrings
();
...
...
@@ -433,12 +437,9 @@ public:
SourceInfo
(
BoxedModule
*
m
,
ScopingAnalysis
*
scoping
,
FutureFlags
future_flags
,
AST
*
ast
,
BoxedString
*
fn
);
~
SourceInfo
();
private:
std
::
unique_ptr
<
LivenessAnalysis
>
liveness_info
;
};
typedef
std
::
v
ector
<
CompiledFunction
*>
FunctionList
;
typedef
llvm
::
TinyPtrV
ector
<
CompiledFunction
*>
FunctionList
;
struct
CallRewriteArgs
;
// A BoxedCode is our implementation of the Python "code" object (such as function.func_code).
...
...
@@ -470,7 +471,7 @@ public:
versions
;
// any compiled versions along with their type parameters; in order from most preferred to least
ExceptionSwitchable
<
CompiledFunction
*>
always_use_version
;
// if this version is set, always use it (for unboxed cases)
std
::
unordered_map
<
const
OSREntryDescriptor
*
,
CompiledFunction
*
>
osr_versions
;
std
::
forward_list
<
std
::
pair
<
const
OSREntryDescriptor
*
,
CompiledFunction
*>
>
osr_versions
;
// Profiling counter:
int
propagated_cxx_exceptions
=
0
;
...
...
src/runtime/util.cpp
View file @
b2a3fb22
...
...
@@ -260,7 +260,7 @@ extern "C" void dumpEx(void* p, int levels) {
printf
(
"A builtin function
\n
"
);
}
printf
(
"Has %
ld
function versions
\n
"
,
md
->
versions
.
size
());
printf
(
"Has %
u
function versions
\n
"
,
md
->
versions
.
size
());
for
(
CompiledFunction
*
cf
:
md
->
versions
)
{
bool
got_name
;
if
(
cf
->
exception_style
==
CXX
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment