Skip to content

Commit bee756c

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/allow-conditional-esm-consumption
2 parents ccef166 + e98367c commit bee756c

File tree

4 files changed

+54
-1
lines changed

4 files changed

+54
-1
lines changed

test-app/app/src/main/assets/app/mainpage.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ require("./tests/testPostFrameCallback");
7070
require("./tests/console/logTests.js");
7171
require('./tests/testURLImpl.js');
7272
require('./tests/testURLSearchParamsImpl.js');
73+
require('./tests/testPerformanceNow');
7374

7475
// ES MODULE TESTS
7576
__log("=== Running ES Modules Tests ===");
76-
require("./tests/testESModules");
77+
require("./tests/testESModules");
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
describe('performance.now()', () => {
2+
it('returns increasing high-resolution time', () => {
3+
const t1 = performance.now();
4+
const t2 = performance.now();
5+
expect(typeof t1).toBe('number');
6+
expect(isNaN(t1)).toBe(false);
7+
expect(t2).not.toBeLessThan(t1); // non-decreasing
8+
// Should be relative (well below 1h after startup)
9+
expect(t1).toBeLessThan(60 * 60 * 1000);
10+
});
11+
12+
it('advances over real time', (done) => {
13+
const t1 = performance.now();
14+
setTimeout(() => {
15+
const t2 = performance.now();
16+
// 8ms threshold accounts for timer clamping on some devices
17+
expect(t2 - t1).not.toBeLessThan(8);
18+
done();
19+
}, 10);
20+
});
21+
});

test-app/runtime/src/main/cpp/Runtime.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "URLImpl.h"
3737
#include "URLSearchParamsImpl.h"
3838
#include "URLPatternImpl.h"
39+
#include <chrono>
3940

4041
#ifdef APPLICATION_IN_DEBUG
4142
// #include "NetworkDomainCallbackHandlers.h"
@@ -489,6 +490,10 @@ Isolate* Runtime::PrepareV8Runtime(const string& filesPath, const string& native
489490

490491
tns::instrumentation::Frame isolateFrame;
491492
auto isolate = Isolate::New(create_params);
493+
// Capture start and realtime origin
494+
// MonotonicallyIncreasingTime returns seconds as double; store for performance.now()
495+
m_startTime = platform->MonotonicallyIncreasingTime();
496+
m_realtimeOrigin = platform->CurrentClockTimeMillis();
492497
isolateFrame.log("Isolate.New");
493498

494499
s_isolate2RuntimesCache[isolate] = this;
@@ -531,6 +536,15 @@ Isolate* Runtime::PrepareV8Runtime(const string& filesPath, const string& native
531536
globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__exit"), FunctionTemplate::New(isolate, CallbackHandlers::ExitMethodCallback));
532537
globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__runtimeVersion"), ArgConverter::ConvertToV8String(isolate, NATIVE_SCRIPT_RUNTIME_VERSION), readOnlyFlags);
533538
globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__time"), FunctionTemplate::New(isolate, CallbackHandlers::TimeCallback));
539+
540+
// performance object (performance.now() + timeOrigin)
541+
{
542+
auto performanceTemplate = ObjectTemplate::New(isolate);
543+
auto nowFunc = FunctionTemplate::New(isolate, Runtime::PerformanceNowCallback);
544+
performanceTemplate->Set(ArgConverter::ConvertToV8String(isolate, "now"), nowFunc);
545+
performanceTemplate->Set(ArgConverter::ConvertToV8String(isolate, "timeOrigin"), Number::New(isolate, m_realtimeOrigin));
546+
globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "performance"), performanceTemplate);
547+
}
534548
globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__releaseNativeCounterpart"), FunctionTemplate::New(isolate, CallbackHandlers::ReleaseNativeCounterpartCallback));
535549
globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__markingMode"), Number::New(isolate, m_objectManager->GetMarkingMode()), readOnlyFlags);
536550
globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__runOnMainThread"), FunctionTemplate::New(isolate, CallbackHandlers::RunOnMainThreadCallback));
@@ -749,6 +763,14 @@ void Runtime::SetManualInstrumentationMode(jstring mode) {
749763
}
750764
}
751765

766+
void Runtime::PerformanceNowCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
767+
auto isolate = args.GetIsolate();
768+
auto runtime = Runtime::GetRuntime(isolate);
769+
// Difference in seconds * 1000 for ms
770+
double ms = (platform->MonotonicallyIncreasingTime() - runtime->m_startTime) * 1000.0;
771+
args.GetReturnValue().Set(ms);
772+
}
773+
752774
void Runtime::DestroyRuntime() {
753775
s_id2RuntimeCache.erase(m_id);
754776
s_isolate2RuntimesCache.erase(m_isolate);

test-app/runtime/src/main/cpp/Runtime.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,15 @@ class Runtime {
108108

109109
bool m_isMainThread;
110110

111+
// High resolution timing origin values
112+
// m_startTime: monotonic clock time captured at isolate creation
113+
// m_realtimeOrigin: wall-clock time origin (milliseconds) captured at isolate creation
114+
double m_startTime {0};
115+
double m_realtimeOrigin {0};
116+
117+
// performance.now() callback
118+
static void PerformanceNowCallback(const v8::FunctionCallbackInfo<v8::Value>& args);
119+
111120
v8::Isolate* PrepareV8Runtime(const std::string& filesPath, const std::string& nativeLibsDir, const std::string& packageName, bool isDebuggable, const std::string& callingDir, const std::string& profilerOutputDir, const int maxLogcatObjectSize, const bool forceLog);
112121
jobject ConvertJsValueToJavaObject(JEnv& env, const v8::Local<v8::Value>& value, int classReturnType);
113122
static int GetAndroidVersion();

0 commit comments

Comments
 (0)