How to reduce frequent scavenge in V8 - javascript

This is my test code
function Obj ()
{
}
function genObj ()
{
return new Obj()
}
globalThis.objPool = new Array( 1_000_000 )
function test ()
{
globalThis.objPool.length = 0
for ( var i = 0; i < 1_000_000; i++ )
{
globalThis.objPool.push( genObj() )
}
}
test()
This is d8 trace gc result
d8 --trace-gc test.js
[35164:000001B1DE2EBBA0] 120 ms: Scavenge 5.0 (5.4) -> 1.0 (2.6) MB, 5.74 / 0.00 ms (average mu = 1.000, current mu = 1.000) allocation failure;
[35164:000001B1DE2EBBA0] 134 ms: Scavenge 2.2 (3.3) -> 1.8 (3.7) MB, 12.10 / 0.00 ms (average mu = 1.000, current mu = 1.000) allocation failure;
[35164:000001B1DE2EBBA0] 155 ms: Scavenge 2.6 (4.1) -> 2.6 (6.6) MB, 18.12 / 0.00 ms (average mu = 1.000, current mu = 1.000) allocation failure;
[35164:000001B1DE2EBBA0] 189 ms: Scavenge 5.7 (8.3) -> 5.2 (7.9) MB, 28.67 / 0.00 ms (average mu = 1.000, current mu = 1.000) allocation failure;
[35164:000001B1DE2EBBA0] 231 ms: Scavenge 6.9 (9.3) -> 6.8 (15.1) MB, 36.22 / 0.00 ms (average mu = 1.000, current mu = 1.000) allocation failure;
[35164:000001B1DE2EBBA0] 296 ms: Scavenge 12.6 (17.3) -> 12.9 (17.3) MB, 55.07 / 0.00 ms (average mu = 1.000, current mu = 1.000) allocation failure;
[35164:000001B1DE2EBBA0] 356 ms: Scavenge 12.9 (17.3) -> 12.6 (29.3) MB, 58.69 / 0.00 ms (average mu = 1.000, current mu = 1.000) allocation failure;
[35164:000001B1DE2EBBA0] 426 ms: Mark-Compact 17.7 (32.6) -> 14.1 (31.2) MB, 14.08 / 0.01 ms (+ 13.4 ms in 30 steps since start of marking, biggest step 0.8 ms, walltime since start of marking 61 ms) (average mu = 1.000, current mu = 1.000) finalize incremental marking via stack guard; GC in old space requested
Multiple gc were triggered in the test code, which affected performance.
It seems that the Obj have allocated young generation, so I want to allocate them to old generation. Is there any way to allocate new objects to the old generation, so as to reduce scavenge gc?

(V8 developer here.)
Is there any way to allocate new objects to the old generation, so as to reduce scanvange gc?
No. Objects are allocated in the young generation. Sometimes V8 will automatically decide that certain allocations should be "pretenured" (i.e. allocated in the old generation directly) because the objects are estimated to be long-lived based on past behavior of the application, but you can't control that manually. That doesn't seem to be happening for this microbenchmark, but since it's a microbenchmark, it also shouldn't be the scenario that the heuristics are targeting.
In summary: don't worry about it.

Related

xtermjs doesn't display correctly and shows crooked text

I'm saving data from a tmux session with capture-pane into a file.txt and I get for instance this result:
PC1:/path$ cd /usr
PC1:/usr$ ll
total 0
drwxr-xr-x 1 root root 4096 May 21 2019 [1;34m.[0;39m/
drwxr-xr-x 1 root root 4096 Aug 1 2019 [1;34m..[0;39m/
drwxr-xr-x 1 root root 4096 Mar 17 15:09 [1;34mbin[0;39m/
drwxr-xr-x 1 root root 4096 Apr 12 2016 [1;34mgames[0;39m/
drwxr-xr-x 1 root root 4096 Feb 8 09:44 [1;34minclude[0;39m/
drwxr-xr-x 1 root root 4096 Feb 8 09:44 [1;34mlib[0;39m/
drwxr-xr-x 1 root root 4096 Nov 26 14:52 [1;34mlocal[0;39m/
drwxr-xr-x 1 root root 4096 May 21 2019 [1;34msbin[0;39m/
drwxr-xr-x 1 root root 4096 Feb 8 09:44 [1;34mshare[0;39m/
drwxr-xr-x 1 root root 4096 May 21 2019 [1;34msrc[0;39m/
PC1:/usr$`
If I do cat file.txt it displays correctly with colors. If I write that some data to xtermjs it shows all crooked:
I've tried:
Adjusting the cols, rows on the Terminal options (I get the current columns and rows with tput cols and tput lines on linux)
Using "xterm-addon-fit"
I've tried several ways of loading the file just to see if I'm not losing some information in the copy/pasting
I tried with the package xterm-for-reacth
I also tried vanilla js but had the same issues
Nothing worked. At this moment I just want to find a way of getting the text from a tmux session and display it correctly on xtermjs.
You can see the issue in this codesandbox.
edit:
xtermjs only accepts CRLF (aka \r\n) so if the \r is converted to \r\n will make it work.
I had several wrong assumptions:
That xtermjs write would process line endings (as it processes everything else)
There were tabs on my text
I only found out the issue when I rendered the line endings and noticed there were no tabs at the start.
The weirdness in the image above is just the word wrap. xterm works focused on adding lines and not loading full screens.
The example below works albeit only for testing purposes.
import { useEffect } from "react";
import { Terminal } from "xterm";
import "./styles.css";
import "xterm/css/xterm.css";
const txt = `
PC1:/path$ cd /usr
PC1:/usr$ ll
total 0
drwxr-xr-x 1 root root 4096 May 21 2019 [1;34m.[0;39m/
drwxr-xr-x 1 root root 4096 Aug 1 2019 [1;34m..[0;39m/
drwxr-xr-x 1 root root 4096 Mar 17 15:09 [1;34mbin[0;39m/
drwxr-xr-x 1 root root 4096 Apr 12 2016 [1;34mgames[0;39m/
drwxr-xr-x 1 root root 4096 Feb 8 09:44 [1;34minclude[0;39m/
drwxr-xr-x 1 root root 4096 Feb 8 09:44 [1;34mlib[0;39m/
drwxr-xr-x 1 root root 4096 Nov 26 14:52 [1;34mlocal[0;39m/
drwxr-xr-x 1 root root 4096 May 21 2019 [1;34msbin[0;39m/
drwxr-xr-x 1 root root 4096 Feb 8 09:44 [1;34mshare[0;39m/
drwxr-xr-x 1 root root 4096 May 21 2019 [1;34msrc[0;39m/
PC1:/usr$`;
let terminal;
export default function App() {
useEffect(() => {
terminal = new Terminal();
terminal.open(document.getElementById("terminal"));
const lines = txt.split(/\n/);
lines.forEach((l) => terminal.write(l + "\r\n"));
}, []);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<div id="terminal" />
</div>
);
}

What is LdaKeyedProperty in V8 byte code?

This is a sample V8 byte code.
984 E> 00000318BA8792D3 # 41 : 29 02 07 LdaKeyedProperty a0, [7]
"Ld" means "load" (from memory)
"a" means "to the accumulator register" (as most bytecodes)
"KeyedProperty" means it's for JS code like obj[index] (as opposed to a "named property" like obj.foo).

NodeJS - Converting MTC (Midi Timecode) "quater message" into a full timecode string

So here's my problem. I'm working on a script in NodeJS, that will take an MTC, or MIDI Timecode signal, and eventually, trigger different things off of certain points in said timecode.
The issue I'm having currently is that the current Timecode clock program I am using, sends the MIDI timecode message as what is known as a "quarter frame" message. Put simply, it sends, in hex, eight consecutive messages, that altogether make up the hh:mm:ss:ff (hour, minute, second, frame) format. If the first message is 00, that means that the units digit of the frames number is 0 (still in hex), if the second message is 15, from the 1, that means that the frames tens digit is 5. That's a super dodgy explanation, so here is the only valid documentation I could find to explain it.
I managed to find another StackOverflow question that is the same, except the code provided is in C#, and I don't know how to translate that over to JavaScript with my limited knowledge. Here is that question.
Thanks in advance
There is a library named JZZ.js that, among other things, allows to convert sequential MTC into a time code.
A code snippet is available at https://jazz-soft.net/doc/JZZ/smpte.html#read
code:
var master = JZZ.SMPTE(); // master clock
var slave = JZZ.SMPTE(); // slave clock
var sender = JZZ.Widget(); // sending port
var receiver = JZZ.Widget(); // receiving port
receiver._receive = function(msg) {
if (slave.read(msg)) // print and consume the MTC messages
console.log(master.toString(), ' ==> ', msg.toString(), ' ==> ', slave.toString());
else _emit(msg); // forward all other MIDI messages
};
sender.connect(receiver);
master.reset(24, 7, 39, 59); // 7:40 it arrives...
for (var n = 0; n < 25; n++) {
sender.mtc(master);
master.incrQF();
}
output:
07:39:59:00 ==> f1 00 -- MIDI Time Code ==> 00:00:00:00
07:39:59:00 ==> f1 10 -- MIDI Time Code ==> 00:00:00:00
07:39:59:00 ==> f1 2b -- MIDI Time Code ==> 00:00:00:00
07:39:59:00 ==> f1 33 -- MIDI Time Code ==> 00:00:00:00
07:39:59:01 ==> f1 47 -- MIDI Time Code ==> 00:00:00:01
07:39:59:01 ==> f1 52 -- MIDI Time Code ==> 00:00:00:01
07:39:59:01 ==> f1 67 -- MIDI Time Code ==> 00:00:00:01
07:39:59:01 ==> f1 70 -- MIDI Time Code ==> 00:00:00:01
07:39:59:02 ==> f1 02 -- MIDI Time Code ==> 07:39:59:02
07:39:59:02 ==> f1 10 -- MIDI Time Code ==> 07:39:59:02
07:39:59:02 ==> f1 2b -- MIDI Time Code ==> 07:39:59:02
07:39:59:02 ==> f1 33 -- MIDI Time Code ==> 07:39:59:02
07:39:59:03 ==> f1 47 -- MIDI Time Code ==> 07:39:59:03
07:39:59:03 ==> f1 52 -- MIDI Time Code ==> 07:39:59:03
07:39:59:03 ==> f1 67 -- MIDI Time Code ==> 07:39:59:03
07:39:59:03 ==> f1 70 -- MIDI Time Code ==> 07:39:59:03
07:39:59:04 ==> f1 04 -- MIDI Time Code ==> 07:39:59:04
07:39:59:04 ==> f1 10 -- MIDI Time Code ==> 07:39:59:04
07:39:59:04 ==> f1 2b -- MIDI Time Code ==> 07:39:59:04
07:39:59:04 ==> f1 33 -- MIDI Time Code ==> 07:39:59:04
07:39:59:05 ==> f1 47 -- MIDI Time Code ==> 07:39:59:05
07:39:59:05 ==> f1 52 -- MIDI Time Code ==> 07:39:59:05
07:39:59:05 ==> f1 67 -- MIDI Time Code ==> 07:39:59:05
07:39:59:05 ==> f1 70 -- MIDI Time Code ==> 07:39:59:05
07:39:59:06 ==> f1 06 -- MIDI Time Code ==> 07:39:59:06

Run Azure Function every 10 minutes starting at 1 second before each 00:x0

An Azure Function must run every 10 minutes indefinitely starting at 00:59:59 (hour, minute, seconds). The cron schedule I am using is unsuccessful.
I am using a Javascript Azure Function based on a timer, e.g.,
module.exports = async function (context, myTimer) {
var timeStamp = new Date().toISOString();
I don't believe there is a setting within an Azure Function to set a start date/time. The cron scheduler seems like the only option.
According to the Azure Functions documentation:
The schedule expression is a CRON expression that includes 6 fields:
{second} {minute} {hour} {day} {month} {day of the week}
Note that many of the cron expressions you find online omit the {second} field, so if you copy from one of those you'll have to adjust for the extra field.
Examples provided by the documentation:
To trigger once every 5 minutes: 0 */5 * * * *
To trigger at 9:30 AM every day: 0 30 9 * * *
59 */10 * * * * results in these execution times:
Result: 11:40:59 | Desired: 11:39:59
Result: 11:30:59 | Desired: 11:29:59
Result: 11:20:59 | Desired: 11:19:59
Result: 11:10:59 | Desired: 11:09:59
59 */10-1 * * * * is not supported.
The reason the Azure Function needs to start its initial run at 00:59:59 is that the function compares event timestamps that occurred in the previous 10 minutes to a 10-minute UTC time interval. If any event timestamps to the minute level match a the UTC timestamp within the interval to the minute level (e.g., 2018-12-21Txx:3x:xx.xxxZ of the event at 2018-12-21T00:35:18.894Z matches any UTC timestamp of this pattern 2018-12-21Txx:3x:xx.xxxZ), an action is performed.)
I am stuck. Any help is appreciated. Thank you.
It's a bit of a mouthful, but what you want is 59 9,19,29,39,49,59 * * * *.

positioning entries on a timeline

Hello I have calender/schedule in an app that looks similar to this very basic example,
| Jan | Feb | Mar | Apr | Jun | Jul | Aug | Sep | Oct | Nov | Dec |
Project #1 (Runs from start of Jan to mid March) ...............
Project #2 (Runs from mid march to early september)
..............................
The dots under the project title illustrate the length of the project, what I am struggling with is giving the entry the correct value of left margin to push the project to the correct start date.
The figures I have available to me are:
Number of days the projects run,
Number of days between the 01/01/2014 and the first days of the project.
Total number of days in the calendar (the calendar runs Jan 2014 - Dec 2019).
Width of the container holding the calendar.
I thought it would be something like this:
var remainder = number_of_days_in_calendar - this.model.get('num_days_from_year_start');
var decimal = remainder / number_of_days_in_calendar;
var marginLeft = decimal * 100 + "%";
But this returns percentages far too close together there is barely any difference between, Jan and August.
I have worked out the project length successful using this sum,
var width = (parseInt(this.model.get('run_number_days')) / number_of_days_in_calendar) * 100;
this.$el.width(width + "%");
But nothing similar works for positioning the projects.
Calculate the margin based on the total width of the calendar on screen.
width = calendar width in pixels * decimal
If I understand correctly decimal in your calculation is the percentage of days before the project start to the total number of days in the calendar.
Let's say we have these values
number_of_days_in_calendar = 365
day_when_project_started = 91
container_width = 365px
this is how we could calculate the position of left margin
((91 / 365) * 100) * (365px / 365) = margin-left: 24.93%
If the container is, for instance 730px wide, according to the formula above, the final result would be margin-left: 49.86%;

Categories