idlize

Форк
0
354 строки · 10.4 Кб
1
/*
2
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3
 * Licensed under the Apache License, Version 2.0 (the "License");
4
 * you may not use this file except in compliance with the License.
5
 * You may obtain a copy of the License at
6
 *
7
 * http://www.apache.org/licenses/LICENSE-2.0
8
 *
9
 * Unless required by applicable law or agreed to in writing, software
10
 * distributed under the License is distributed on an "AS IS" BASIS,
11
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 * See the License for the specific language governing permissions and
13
 * limitations under the License.
14
 */
15

16
#include <algorithm>
17
#include <chrono>
18
#include <iomanip>
19
#include <unordered_map>
20
#include <vector>
21
#include "common-interop.h"
22
#include "DeserializerBase.h"
23

24
CustomDeserializer* DeserializerBase::customDeserializers = nullptr;
25

26
#if KOALA_INTEROP_PROFILER
27
#include "profiler.h"
28

29
InteropProfiler* InteropProfiler::_instance = nullptr;
30

31
#endif
32

33
using std::string;
34

35
#ifdef KOALA_NAPI
36
static Napi::Reference<Napi::Function> g_koalaNapiCallbackDispatcher;
37

38
void impl_SetCallbackDispatcher(Napi::Object dispatcher) {
39
    g_koalaNapiCallbackDispatcher = Napi::Reference<Napi::Function>::New(dispatcher.As<Napi::Function>(), 1);
40
}
41
KOALA_INTEROP_V1(SetCallbackDispatcher, Napi::Object)
42

43
void impl_CleanCallbackDispatcher() {
44
    if (!g_koalaNapiCallbackDispatcher.IsEmpty()) {
45
        g_koalaNapiCallbackDispatcher.Reset();
46
    }
47
}
48
KOALA_INTEROP_V0(CleanCallbackDispatcher)
49

50
napi_value getKoalaNapiCallbackDispatcher() {
51
    if (g_koalaNapiCallbackDispatcher.IsEmpty()) {
52
        abort();
53
    }
54
    return (napi_value)g_koalaNapiCallbackDispatcher.Value();
55
}
56
#endif
57

58
KInt impl_StringLength(KNativePointer ptr) {
59
    string* s = reinterpret_cast<string*>(ptr);
60
    return s->length();
61
}
62
KOALA_INTEROP_1(StringLength, KInt, KNativePointer)
63

64
void impl_StringData(KNativePointer ptr, KByte* bytes, KUInt size) {
65
    string* s = reinterpret_cast<string*>(ptr);
66
    if (s) memcpy(bytes, s->c_str(), size);
67
}
68
KOALA_INTEROP_V3(StringData, KNativePointer, KByte*, KUInt)
69

70
KNativePointer impl_StringMake(const KStringPtr& str) {
71
    return new string(str.c_str());
72
}
73
KOALA_INTEROP_1(StringMake, KNativePointer, KStringPtr)
74

75
// For slow runtimes w/o fast encoders.
76
KInt impl_ManagedStringWrite(const KStringPtr& string, KByte* buffer, KInt offset) {
77
    memcpy(buffer + offset, string.c_str(), string.length() + 1);
78
    return string.length() + 1;
79
}
80
KOALA_INTEROP_3(ManagedStringWrite, KInt, KStringPtr, KByte*, KInt)
81

82
void stringFinalizer(string* ptr) {
83
    delete ptr;
84
}
85
KNativePointer impl_GetStringFinalizer() {
86
    return fnPtr<string>(stringFinalizer);
87
}
88
KOALA_INTEROP_0(GetStringFinalizer, KNativePointer)
89

90
void impl_InvokeFinalizer(KNativePointer obj, KNativePointer finalizer) {
91
    auto finalizer_f = reinterpret_cast<void (*)(KNativePointer)>(finalizer);
92
    finalizer_f(obj);
93
}
94
KOALA_INTEROP_V2(InvokeFinalizer, KNativePointer, KNativePointer)
95

96
void disposeNodeTmp(KNativePointer* ptr) {
97
}
98

99
KNativePointer impl_GetNodeFinalizer() {
100
    return fnPtr<KNativePointer>(disposeNodeTmp);
101
}
102

103
KOALA_INTEROP_0(GetNodeFinalizer, KNativePointer)
104

105
KInt impl_GetPtrVectorSize(KNativePointer ptr) {
106
    return reinterpret_cast<std::vector<void*>*>(ptr)->size();
107
}
108
KOALA_INTEROP_1(GetPtrVectorSize, KInt, KNativePointer)
109

110
KNativePointer impl_GetPtrVectorElement(KNativePointer ptr, KInt index) {
111
    auto vector = reinterpret_cast<std::vector<void*>*>(ptr);
112
    auto element = vector->at(index);
113
    return nativePtr(element);
114
}
115
KOALA_INTEROP_2(GetPtrVectorElement, KNativePointer, KNativePointer, KInt)
116

117
inline KUInt unpackUInt(const KByte* bytes) {
118
    return (bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24));
119
}
120

121
std::vector<KStringPtr> makeStringVector(KStringArray strArray) {
122
    if (strArray == nullptr) {
123
        return std::vector<KStringPtr>(0);
124
    }
125
    KUInt arraySize = unpackUInt(strArray);
126
    std::vector<KStringPtr> res(arraySize);
127
    size_t offset = sizeof(KUInt);
128
    for (KUInt i = 0; i < arraySize; ++i) {
129
        int len = unpackUInt(strArray + offset);
130
        res[i].assign((const char*)(strArray + offset + sizeof(KUInt)), len);
131
        offset += len + sizeof(KUInt);
132
    }
133
    return res;
134
}
135

136
std::vector<KStringPtr> makeStringVector(KNativePointerArray arr, KInt length) {
137
    if (arr == nullptr) {
138
        return std::vector<KStringPtr>(0);
139
    } else {
140
        std::vector<KStringPtr> res(length);
141
        char** strings = reinterpret_cast<char**>(arr);
142
        for (KInt i = 0; i < length; ++i) {
143
            const char* str = reinterpret_cast<const char*>(strings[i]);
144
            res[i].assign(str);
145
        }
146
        return res;
147
    }
148
}
149

150
struct Log {
151
    std::string log;
152
    bool isActive;
153
};
154
std::vector<Log> groupedLogs;
155

156
void startGroupedLog(KInt index) {
157
    if (index < 0) return;
158
    if (index >= (int)groupedLogs.size()) {
159
        groupedLogs.resize(index + 1);
160
    }
161
    groupedLogs[index] = Log{std::string(), true};
162
}
163

164
void stopGroupedLog(KInt index) {
165
    if (index >=0 && index < (int)groupedLogs.size()) {
166
        groupedLogs[index].isActive = false;
167
    }
168
}
169

170
void appendGroupedLog(KInt index, const std::string& str) {
171
    if (index < 0) return;
172
    if (index >= (int)groupedLogs.size()) {
173
        groupedLogs.resize(index + 1);
174
        groupedLogs[index].isActive = true;
175
    }
176
    groupedLogs[index].log.append(str);
177
}
178

179
std::string emptyString;
180

181
const std::string& getGroupedLog(int32_t index) {
182
    if (index >=0 && index < (int)groupedLogs.size()) {
183
        return groupedLogs[index].log;
184
    }
185
    return emptyString;
186
}
187

188
const bool needGroupedLog(int32_t index) {
189
    if (index >=0 && index < (int)groupedLogs.size()) {
190
        return groupedLogs[index].isActive;
191
    }
192
    return false;
193
}
194

195
KNativePointer impl_GetGroupedLog(KInt index) {
196
    return new std::string(getGroupedLog(index));
197
}
198
KOALA_INTEROP_1(GetGroupedLog, KNativePointer, KInt)
199

200
void impl_StartGroupedLog(KInt index) {
201
    startGroupedLog(index);
202
}
203
KOALA_INTEROP_V1(StartGroupedLog, KInt)
204

205
void impl_StopGroupedLog(KInt index) {
206
    stopGroupedLog(index);
207
}
208
KOALA_INTEROP_V1(StopGroupedLog, KInt)
209

210
KInt impl_TestPerfNumber(KInt value) {
211
    return value + 1;
212
}
213
KOALA_INTEROP_1(TestPerfNumber, KInt, KInt)
214

215
void impl_TestPerfNumberWithArray(KByte* data, KInt length) {
216
    if (needGroupedLog(1)) {
217
        string out("TestPerfNumberWithArray(");
218
        out.append(std::to_string(data[0]));
219
        out.append(", ");
220
        out.append(std::to_string(length));
221
        out.append(")");
222
        appendGroupedLog(1, out);
223
    }
224
}
225
KOALA_INTEROP_V2(TestPerfNumberWithArray, KByte*, KInt)
226

227
Performace* Performace::GetInstance() {
228
    static Performace perf;
229
    return &perf;
230
}
231

232
PerfInfo& Performace::GetCurrent() {
233
    return current_;
234
}
235

236
void Performace::FinishOne() {
237
    perfs_[current_.perf_name].emplace_back(current_);
238
}
239

240
void Performace::CalcSelfCost() {
241
    float totalCost = 0.0;
242
    auto it = perfs_.find("perf_counter_self_cost");
243
    if (it == perfs_.end()) {
244
        self_cost_ = totalCost;
245
        return;
246
    }
247

248
    for (const auto& perf : it->second) {
249
        totalCost += perf.cost / 1000.0;
250
    }
251
    self_cost_ = totalCost / it->second.size();
252
}
253

254
void Performace::PrintTotals(std::stringstream& result) {
255
    for (const auto& [name, perfs] : perfs_) {
256
        float totalCost = 0;
257
        for (const auto& perf : perfs) {
258
            totalCost += perf.cost / 1000.0 - self_cost_;
259
        }
260
        result << "Perf trace_name(" << name << ") " << perfs.size() << " call total cost " << totalCost << " us.";
261
    }
262
}
263

264
void Performace::PrintAvgs(std::stringstream& result) {
265
    for (const auto& [name, perfs] : perfs_) {
266
        if (name == "perf_counter_self_cost") continue;
267
        float totalCost = 0;
268
        for (const auto& perf : perfs) {
269
            totalCost += perf.cost / 1000.0 - self_cost_;
270
        }
271
        auto avg = totalCost / perfs.size();
272
        result << "Perf trace_name(" << name << ") " << perfs.size() << " call avg cost " << avg << " us.";
273
    }
274
}
275

276
void Performace::PrintPeak(std::stringstream& result) {
277
    for(auto &kv : perfs_) {
278
        std::sort(kv.second.begin(), kv.second.end(), [](const PerfInfo &perf1, const PerfInfo &perf2) {
279
            return perf1.cost > perf2.cost;
280
        });
281
        auto maxCost = kv.second.front().cost / 1000.0 - self_cost_;
282
        auto minCost = kv.second.back().cost / 1000.0 - self_cost_;
283
        result << "Perf trace_name(" << kv.first << ") " << " maxCost = " << maxCost << " us, ";
284
        result << "minCost = " << minCost << " us.";
285
    }
286
}
287

288
void Performace::PrintDetails(std::stringstream& result) {
289
    for (const auto& [name, perfs] : perfs_) {
290
        for (auto perf : perfs) {
291
            perf.Print(result);
292
        }
293
    }
294
}
295

296
void Performace::Clean() {
297
    perfs_.clear();
298
}
299

300
void PerfInfo::Print(std::stringstream& result, float counterSelf) {
301
    result << "Perf trace_name(" << perf_name <<  ") cost " << (cost / 1000.0 - counterSelf) << " us.";
302
}
303

304
void impl_StartPerf(const KStringPtr& traceName) {
305
    PerfInfo& perf = Performace::GetInstance()->GetCurrent();
306
    perf.perf_name = traceName.c_str();
307
    auto now = std::chrono::high_resolution_clock::now();
308
    perf.start = std::chrono::time_point_cast<std::chrono::nanoseconds>(now).time_since_epoch().count();
309
}
310
KOALA_INTEROP_V1(StartPerf, KStringPtr)
311

312
void impl_EndPerf(const KStringPtr& traceName) {
313
    auto now = std::chrono::high_resolution_clock::now();
314
    PerfInfo& perf = Performace::GetInstance()->GetCurrent();
315
    perf.end = std::chrono::time_point_cast<std::chrono::nanoseconds>(now).time_since_epoch().count();
316
    perf.cost = perf.end - perf.start;
317
    Performace::GetInstance()->FinishOne();
318
}
319
KOALA_INTEROP_V1(EndPerf, KStringPtr)
320

321
enum DumpOptions {
322
  TOTAL,
323
  AVERAGE,
324
  PEAK,
325
  DETAILS,
326
  CLEAR
327
};
328

329
KNativePointer impl_DumpPerf(KInt options) {
330
    std::stringstream result;
331
    result << std::fixed << std::setprecision(3);
332
    Performace::GetInstance()->CalcSelfCost();
333
    switch (options) {
334
        case TOTAL:
335
            Performace::GetInstance()->PrintTotals(result);
336
            break;
337
        case AVERAGE:
338
            Performace::GetInstance()->PrintAvgs(result);
339
            break;
340
        case PEAK:
341
            Performace::GetInstance()->PrintPeak(result);
342
            break;
343
        case DETAILS:
344
            Performace::GetInstance()->PrintDetails(result);
345
            break;
346
        case CLEAR:
347
            Performace::GetInstance()->Clean();
348
            break;
349
        default:
350
            break;
351
    }
352
    return new std::string(result.str());
353
}
354
KOALA_INTEROP_1(DumpPerf, KNativePointer, KInt)

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.