What's the difference between if statement and branch statement in v8 CSA.

153 views
Skip to first unread message

18楼梦想改造家

unread,
Sep 1, 2024, 11:17:34 PM9/1/24
to v8-dev
Hi:

      I try to read/understand some code in v8 csa sub-system, like this:

``` c++
  DebugBreak(); // [+] @a
  if (IsHoleyElementsKind(kind)) {   // [+] if statement
    condition = UintPtrGreaterThanOrEqual(key, length);
  } else {
    DebugBreak(); // [+] @b
    // We don't support growing here unless the value is being appended.
    condition = WordEqual(key, length);
  }
  Branch(condition, &grow_case, &no_grow_case);  // [+] Branch statement
```
I inserted two breakpoints at points A and B. I originally thought that between these two breakpoints, the code corresponding to |IsHoleyElementsKind(kind)| would be generated to check |kind|. However, it was not the case. There is no other code between the two |DebugBreak| instructions.  

``` c++
00007ff6`97326605 cc int 3
00007ff6`97326606 cc int 3
00007ff6`97326607 4d8be0 mov r12,r8

```

This means that my assumption was obviously wrong. It seems that I confused the difference between the if keyword and the Branch keyword. So, I came up with the following hypothesis:

  1. If we want to achieve an effect similar to if in CSA, we need to use keywords like Branch.
  2. What is the role of if in CSA? I suspect that it is handled by mksnapshot to generate different backup codes for different kind. Suppose there are five kinds in total, then five similar pieces of code would be generated.

Please tell me if my assumption is correct. If not, what is the difference between if and Branch in CSA?

If my assumption is correct, it seems that the kind should only be determined at runtime, so how does V8 know which piece of code to use?

Thank you.



Nico Hartmann

unread,
Sep 2, 2024, 8:27:40 AM9/2/24
to v8-...@googlegroups.com
Hi,

In CSA (or any other type of graph builder used in V8 for that matter), there are two different things:
1.) C++ statements that are executed when the builder is run to generate code (e.g. when you compile a function or when builtins or bytecode handlers are generated)
2.) Code that is emitted and executed when running whatever is generated here.

In your case, the `Branch` function is a helper that emits a branching instruction into the generated code that will then be executed later when that code is run. The C++ if statement, however, is executed when generating the code and we want to decide what code to generate depending on some information available during compilation time.

Hope that helps,
Nico

--
--
v8-dev mailing list
v8-...@googlegroups.com
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to v8-dev+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/v8-dev/0a76378c-191f-45ad-b1e8-285e041a7890n%40googlegroups.com.


--
Nico Hartmann | Software Engineer | nicoha...@google.com | Chrome - V8

Ben Noordhuis

unread,
Sep 2, 2024, 4:05:39 PM9/2/24
to v8-...@googlegroups.com
On Mon, Sep 2, 2024 at 5:17 AM 18楼梦想改造家 <18.flo...@gmail.com> wrote:
>
To add to Nico's reply -

That code snippet is from CodeStubAssembler::CheckForCapacityGrow(), right?

V8 at that point knows if it's generating machine code for holey or
non-holey objects. It doesn't have to generate a runtime "is holey?"
type check because it already knows and can specialize right away.

18楼梦想改造家

unread,
Sep 3, 2024, 4:23:37 PM9/3/24
to v8-dev
Hi, ben:


>  That code snippet is from CodeStubAssembler::CheckForCapacityGrow(), right?

 Yes.


>  V8 at that point knows if it's generating machine code for holey or
non-holey objects. It doesn't have to generate a runtime "is holey?"
type check because it already knows and can specialize right away.

How did v8 know it is holey or not if we don't have this runtime check? Thanks.

Ben Noordhuis

unread,
Sep 4, 2024, 6:31:53 AM9/4/24
to v8-...@googlegroups.com
On Tue, Sep 3, 2024 at 10:23 PM 18楼梦想改造家 <18.flo...@gmail.com> wrote:
>
> Hi, ben:
>
> > That code snippet is from CodeStubAssembler::CheckForCapacityGrow(), right?
>
> Yes.
>
> > V8 at that point knows if it's generating machine code for holey or
> non-holey objects. It doesn't have to generate a runtime "is holey?"
> type check because it already knows and can specialize right away.
>
> How did v8 know it is holey or not if we don't have this runtime check? Thanks.

Because that code path is only used for typed arrays (non-holey by
definition) or when transitioning (object is in a known state). Grep
for EmitElementStore; the call in src/builtins/builtins-handler-gen.cc
does a type check with a slow path fallback.
Reply all
Reply to author
Forward
0 new messages