@@ -146,6 +146,40 @@ static void GetTotalMemory(const FunctionCallbackInfo<Value>& args) {
146146 args.GetReturnValue ().Set (amount);
147147}
148148
149+ // The calculations in this method are described in the specification:
150+ // https://w3c.github.io/device-memory/.
151+ static void GetApproximatedDeviceMemory (
152+ const FunctionCallbackInfo<Value>& args) {
153+ float approximated_device_memory_gb_ = 0.0 ;
154+ double physical_memory_mb_ =
155+ static_cast <double >(uv_get_total_memory () / (1024 * 1024 ));
156+ DCHECK_GT (physical_memory_mb_, 0 );
157+ int power = 0 ;
158+ int lower_bound = physical_memory_mb_;
159+
160+ // Extract the most-significant-bit and its location.
161+ while (lower_bound > 1 ) {
162+ lower_bound >>= 1 ;
163+ power++;
164+ }
165+ // The remaining should always be equal to exactly 1.
166+ DCHECK_EQ (lower_bound, 1 );
167+
168+ int64_t upper_bound = lower_bound + 1 ;
169+ lower_bound = lower_bound << power;
170+ upper_bound = upper_bound << power;
171+
172+ // Find the closest bound, and convert it to GB.
173+ if (physical_memory_mb_ - lower_bound <= upper_bound - physical_memory_mb_)
174+ approximated_device_memory_gb_ = static_cast <float >(lower_bound) / 1024.0 ;
175+ else
176+ approximated_device_memory_gb_ = static_cast <float >(upper_bound) / 1024.0 ;
177+
178+ // Max-limit the reported value to 8GB to reduce fingerprintability of
179+ // high-spec machines.
180+ if (approximated_device_memory_gb_ > 8 ) approximated_device_memory_gb_ = 8.0 ;
181+ args.GetReturnValue ().Set (approximated_device_memory_gb_);
182+ }
149183
150184static void GetUptime (const FunctionCallbackInfo<Value>& args) {
151185 Environment* env = Environment::GetCurrent (args);
@@ -394,6 +428,10 @@ void Initialize(Local<Object> target,
394428 SetMethod (context, target, " getLoadAvg" , GetLoadAvg);
395429 SetMethod (context, target, " getUptime" , GetUptime);
396430 SetMethod (context, target, " getTotalMem" , GetTotalMemory);
431+ SetMethod (context,
432+ target,
433+ " getApproximatedDeviceMemory" ,
434+ GetApproximatedDeviceMemory);
397435 SetMethod (context, target, " getFreeMem" , GetFreeMemory);
398436 SetMethod (context, target, " getCPUs" , GetCPUInfo);
399437 SetMethod (context, target, " getInterfaceAddresses" , GetInterfaceAddresses);
@@ -415,6 +453,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
415453 registry->Register (GetHostname);
416454 registry->Register (GetLoadAvg);
417455 registry->Register (GetUptime);
456+ registry->Register (GetApproximatedDeviceMemory);
418457 registry->Register (GetTotalMemory);
419458 registry->Register (GetFreeMemory);
420459 registry->Register (GetCPUInfo);
0 commit comments