-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathparser.h
111 lines (89 loc) · 2.72 KB
/
parser.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#ifndef HARB_PARSER_H
#define HARB_PARSER_H
#include <vector>
#include "sparsehash/sparse_hash_set"
#include "rapidjson/reader.h"
#include "rapidjson/filereadstream.h"
#include "ruby_heap_obj.h"
namespace harb {
class Parser {
struct eqstr {
bool operator()(const char* s1, const char* s2) const {
return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0);
}
};
struct HeapDumpHandler {
bool Null() { return true; }
bool Bool(bool b);
bool Int(int i) { return true; }
bool Uint(unsigned u) { return true; }
bool Int64(int64_t i) { return true; }
bool Uint64(uint64_t u) { return true; }
bool Double(double d) { return true; }
bool RawNumber(const char* str, rapidjson::SizeType length, bool copy);
bool String(const char* str, rapidjson::SizeType length, bool copy);
bool StartObject();
bool Key(const char* str, rapidjson::SizeType length, bool copy);
bool EndObject(rapidjson::SizeType memberCount);
bool StartArray();
bool EndArray(rapidjson::SizeType elementCount);
enum State {
kStart = 0,
kFinish,
kInsideObject,
kFinishObject,
kAddress,
kType,
kReferences,
kClass,
kName,
kMemsize,
kFrozen,
kShared,
kValue,
kSize,
kLength,
kStruct,
kImemoType,
kFlags,
kRoot
} state_;
Parser *parser_;
rapidjson::FileReadStream *stream_;
RubyHeapObj *obj_;
size_t obj_start_pos_, obj_end_pos_;
std::vector<uint64_t> refs_to_;
};
typedef google::sparse_hash_set<const char *, std::hash<const char *>, eqstr> StringSet;
int32_t heap_obj_count_;
StringSet intern_strings_;
HeapDumpHandler handler_;
FILE *f_;
char *heap_obj_json_;
size_t heap_obj_json_size_;
const char * get_intern_string(const char *str);
public:
Parser(FILE *f);
~Parser();
RubyHeapObj* create_heap_object(RubyValueType type);
int32_t get_heap_object_count() { return heap_obj_count_; }
const char * current_heap_object_json();
template<typename Func> void parse(Func func) {
fseeko(f_, 0, SEEK_SET);
char buf[16384];
rapidjson::Reader reader;
rapidjson::FileReadStream frs(f_, buf, sizeof(buf));
handler_.state_ = HeapDumpHandler::kStart;
handler_.parser_ = this;
handler_.stream_ = &frs;
while (reader.Parse<rapidjson::kParseStopWhenDoneFlag | rapidjson::kParseNumbersAsStringsFlag>(frs, handler_)) {
func(handler_.obj_);
}
handler_.state_ = HeapDumpHandler::kFinish;
if (reader.HasParseError() && reader.GetParseErrorCode() != rapidjson::kParseErrorDocumentEmpty) {
// TODO: something
}
}
};
}
#endif // HARB_PARSER_H