The hot path for a call performs a check for a specific callee, with a fast mechanism for making JS->JS calls. The code is generated such that it will initially always bail out to the slow path, and the second time the call is executed it will dynamically linked itself to that callee. There are currently two slow paths generated for each callee, the initial one that calls out to relink the code, and a second form that does not. hotPathBegin & hotPathOther are used (along with an offset) to find three things to repatch in the hot path:

(1) The JSFunction* value that is checked, to identify the callee
(2) The jump out to the slow path, so this can be relinked to the second form (which will not attempt to relink – this is stored in coldPathOther).
(3) The call instruction to be linked the callee's code.

The value callReturnLocation points to the call in the cold path to the relink mechanisms. This is used by the dynamic linking mechanisms to lookup the CallLinkInfo record describing the call to be linked, and is also used in exception handling.

G.

On Mar 6, 2009, at 5:40 PM, x yz wrote:


e.g, emitted asm code before/after patch? what does its four pointers do?
MacroAssembler::CodeLocationNearCall callReturnLocation;
MacroAssembler::CodeLocationDataLabelPtr hotPathBegin;
MacroAssembler::CodeLocationNearCall hotPathOther;
MacroAssembler::CodeLocationLabel coldPathOther;
CodeBlock* callee;

anywhere got doc of the JIT implementations?
thanks a lot!
joe


--- On Wed, 3/4/09, Zoltan Herczeg <zherc...@inf.u-szeged.hu> wrote:

From: Zoltan Herczeg <zherc...@inf.u-szeged.hu>
Subject: Re: [webkit-dev] want to port JIT to MIPS - how patchOffset* constant determined?
To: webkit-dev@lists.webkit.org
Date: Wednesday, March 4, 2009, 3:33 PM
Hi,

they generate instructions, which size is known in advance.

Think about the following sequence:
hotPathBegin:
 mov regX, 32bit_const <- 6 bytes (*) (**)
 add regX, regY <- 2 bytes
 jo 32bit_addr <- 5 bytes (*)

* (Note) : these instructions will be modified during
runtime.

** (Note) : there is a short form for "mov regX,
8bit_const", which length
is only 3 bytes, but they force the longer version in such
cases to keep
the size of the instruction.

As you can see, the address of "jo" is always
(hotPathBegin + 6 + 2). They
simply introduce a new constant: patchOffsetXXX = 8, and
use this constant
to access the "jo" instruction later.

In ARM we can't rely on such constant, because the
constant pool can be
placed after any instruction.

hotPathBegin:
 ldr rX, [pc + const_pool_addr] ; 32 bit const
 [...] <- the const pool can be placed here
 add rX, rX, rY
 [...] <- the const pool can be placed here
hotPath2:
 ldr pc, [pc + const_pool_addr] ; 32 bit target address

We need to store both pointers (hotPathBegin and hotPath2).

Zoltan

Zoltan,
Thanks for reply, I'm trying to understand your
example. But,X86
instruction size is from 1 to 17bytes, not constant. I
may misunderstand
your comments?
Many X86 instruction can have imm32 at the end, thus
this pointer can be
used for patch as well as next address after call.
Does Arm have similar
things? or else you still need to figure out why
"patchOffsetOpCallCompareToJump = 9;"? may
be some instruction lengths
relates to the 9?
rgds
joe


--- On Wed, 3/4/09, Zoltan Herczeg
<zherc...@inf.u-szeged.hu> wrote:

From: Zoltan Herczeg
<zherc...@inf.u-szeged.hu>
Subject: Re: [webkit-dev] want to port JIT to MIPS
- how patchOffset*
constant determined?
To: webkit-dev@lists.webkit.org
Date: Wednesday, March 4, 2009, 3:45 AM
On x86, the size of the instructions are fixed. If
you want
to access
multiple instructions in the instruction stream,
you only
need to store
the address of the first one, and can access the
others by
their relative
address. This saves a little memory.

Example (see JIT::linkCall):
 instruction at callLinkInfo->hotPathBegin:
points to
callee comparison
 instruction at
   callLinkInfo->hotPathBegin +
patchOffsetOpCallCompareToJump:
      points to the slow case entry jump

Zoltan

in jit.h, for example:
       static const int
patchOffsetOpCallCompareToJump = 9;
       static const int
patchOffsetPutByIdStructure =
7;
       static const int
patchOffsetPutByIdPropertyMapOffset = 22;
       static const int
patchOffsetGetByIdBranchToSlowCase = 13;
thanks for help, I'm stucked here now.
joe


--- On Sat, 2/28/09, Gavin Barraclough
<barraclo...@apple.com> wrote:

From: Gavin Barraclough
<barraclo...@apple.com>
Subject: Re: [webkit-dev] want to port
JIT to MIPS
- JIT reg usage clean
up?
To: "WebKit Development"
<webkit-dev@lists.webkit.org>
Date: Saturday, February 28, 2009, 12:19
PM
On Feb 27, 2009, at 4:55 PM, x yz wrote:

The regTx seems to be working
registers here,
yet
their definition are regparm(3) registers
for
function
arugments. Such usage would cause
conflict on
other
platforms. May I suggest that we use
individual
defined set
of regs for func i/o argument and
working?

First up, I think you're getting
slightly
confused
about regparm(3).  This is not used
anywhere in
the JS
language JIT, only in WREC.  In some
configurations of the
JIT we use fastcall semantics on x86...
but none
of this is
really relevant to MIPS.  Just ignore all
this.
Stick to
the default MIPS ABI for stub functions.

Reading between the lines, I'm
guessing your
concern
here is that in setting up arguments for
a JIT
stub call you
may trample the JIT's temporary
registers?  If
so, I
think you need to look at the argument
passing
more closely.
The mechanisms to pass arguments to stub
functions pass all
arguments in memory – typically passing
a single
pointer
to the stub functions, which can be used
to
retrieve the
arguments.  This pointer argument can be
set up
immediately
prior to the call, so it does not
interfere with
the regT?
temporaries.  We follow this pattern on
x86-64,
where the
ABI is typically to pass arguments in
registers.
You cannot
trivially change the way this works,
since the
argument
pointer is used for other purposes too
(e.g.
retrieving the
arguments passed into the JIT code from
within the
stubs).

We strongly prefer small, simple,
incremental
changes.  A
patch that tried to both port the JIT to
a new
platform and
to introduce a new argument passing
interface to
the JIT
stub functions sounds unlikely to get
anywhere (a
patch
porting the JIT to a new platform is on
its own
very likely
to be too much more than we'd want to
land in
one
chunk).  I'd suggest that a port
would be wise
to
engineer it's initial solution to fit
one of
the
existing argument passing mechanisms
(these are
selected by
JIT_STUB_ARGUMENT_* switches, to help
find the
relevant
code).  (Alternatively, you're
welcome to
attempt to
port x86-64 to make use of an in-register
argument
passing
solution, which could be hugely useful.
With this
landed
first and separately, a port could then
build on
top of
this.)

As a more direct answer to your question,
you
could
endeavour to make the set of hardware
registers
used as JIT
temporaries non-overlapping with ABI
function
argument
registers on MIPS, but this is unlikely
to be a
general
solution to anything for all platforms,
due to
limited
register availability on some
architectures.

we would put all these definition in
a file
named
regMap.h, then we can remove all
"X86::"
from
other JIT files.

I don't think we'll be keen on
taking
preemptive
changes so far ahead in preparation of a
port.
The first
logical step in porting to a new platform
is still
to start
with WREC, and this requires no changes
in the JIT
directory.  Any refactoring of the
existing JIT
would make
more sense more directly prior to work in
that
area.

cheers,
G.


I'd apperciate if sb can do it
or help me
to do
it.
rgds
joe




--- On Sat, 2/28/09, x yz
<last...@yahoo.com>
wrote:

From: x yz
<last...@yahoo.com>
Subject: Re: [webkit-dev] want
to port
JIT to MIPS
- which calling convention is used here?
To: webkit-dev@lists.webkit.org,
"Zoltan
Herczeg"
<zherc...@inf.u-szeged.hu>
Date: Saturday, February 28,
2009, 7:40
AM
Hi,
Thanks for your help in
advance:)
in JITPropertyAccess.cpp:
  if

(transitionWillNeedStorageRealloc(oldStructure,
newStructure)) {
      pop(X86::ebx);
///pop return
address,
why? for
exception?
#if PLATFORM(X86_64)
///which
convention is
this?




move(Imm32(newStructure->propertyStorageCapacity()),
regT1);  //edx




move(Imm32(oldStructure->propertyStorageCapacity()),
X86::esi);
      move(regT0, X86::edi);
      callTarget = call();
#else
///__cdecl,
yet how
can I know
resizePropertyStorage() use
__cdecl?




push(Imm32(newStructure->propertyStorageCapacity()));




push(Imm32(oldStructure->propertyStorageCapacity()));
      push(regT0);
      callTarget = call();
      addPtr(Imm32(3 *
sizeof(void*)),
X86::esp);
///clean stack
#endif








_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org



http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev




_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org



http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org


http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev




_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org


http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org

http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev



_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org

http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev



_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev



_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev

_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev

Reply via email to