Add recognition of unused Arm opcode to prevent runtime error

47 views
Skip to first unread message

Malek Musleh

unread,
Feb 26, 2015, 11:17:42 AM2/26/15
to v8-u...@googlegroups.com
Hi,

I've instrumented parts of the v8 source code to call a function from an external library, and have been able to get it compiled successfully, but am running into issues at runtime. Specifically, I am running v8 inside an arm simulator, and the instrumentation calls I added are recognized by the arm simulator (i extend ununsed opcode for functionality). However, at runtime I get the v8 error printed to my simulated terminal.

/tmp/script: line 13:  3207 Illegal instruction     /system/v8/arm.release/shell run-deltablue.js


I suspect that because the instrumented call is getting compiled down to the unused opcode, v8 doesn't recognize it and traps. I've grepped through the source code, but couldn't find where it traps based on an illegal instruction. When encountering this specific opcode of my instrumented calls, I want to simply return and not exit out of the run.


Thanks,

Malek

Rodolph Perfetta

unread,
Feb 26, 2015, 2:46:26 PM2/26/15
to v8-u...@googlegroups.com
If I understood correctly you are using a modified arm simulator (not the V8 built-in one) to run V8, and this simulator returns "illegal instruction". V8 does not trap illegal instructions so the options I can think of:
 * your ARM simulator does not support ARMv7 with VFP, which is a requirement for V8
 * your modification to V8 are corrupting code generation and the pc end up in some data.
Did you try running the test on a clean version of V8?

Rodolph.

--
--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups "v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Malek Musleh

unread,
Feb 26, 2015, 3:04:57 PM2/26/15
to v8-u...@googlegroups.com
Hi Rudolph,

Yes, I have been able to run a clean version of v8 on this other ARM
simulator (gem5). I added support to the gem5 simulator to handle this
unused opcode.

I think it might be your second suggestion. In one of my
instrumentations, I inserted the function after a __Push(), where in
other places I placed it at the top of the function body.

Inside KeyedStoreIC and StoreIC::Generate Miss()

void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
// Push receiver, key and value for runtime call.
__ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
StoreDescriptor::ValueRegister());

// start pipeline viewer tracing
m5_enableDebugFlag();

ExternalReference ref =
ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
__ TailCallExternalReference(ref, 3, 1);


Would placing it after the __Push() cause some corruption on the stack?

Separately, I could not find documentation on how to use/run the
built-in arm simulator of v8. Can you provide an example?
> You received this message because you are subscribed to a topic in the
> Google Groups "v8-users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/v8-users/yIwVNMf060A/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to

Rodolph Perfetta

unread,
Feb 26, 2015, 4:11:02 PM2/26/15
to v8-u...@googlegroups.com
What does m5_enableDebugFlag(); do? Just emit a 32-bit instruction? Where to?

For the builtin simulator, on an intel machine simply build the arm target: make arm.release. When the build system detect the mismatch between the host tool ISA and the target ISA it automatically build the simulator.

Malek Musleh

unread,
Feb 26, 2015, 4:24:56 PM2/26/15
to v8-u...@googlegroups.com
The purpose of My m5_enableDebugFlag () is to enable tracing
(dissaembly, cache behavior, etc) within the simulator.

A separate macro within the simulator is invoked for each one of these
magic instructions:

SIMPLE_OP(m5_enableDebugFlag, enable_debugflag_func, 0)
#define enable_debugflag_func 0x5e

In this case the enable_debugflag_func is 0x5e. It ends up moving the
pc to the lr register.


.macro simple_op name, func, subfunc
.align 2
.globl \name
\name:
#ifdef __thumb__
.short 0xEE00 | \func
.short 0x0110 | (\subfunc << 12)
#else
.long 0xEE000110 | (\func << 16) | (\subfunc << 12)
#endif
mov pc,lr


I notice in the v8 code comment at the beginning of the ::GenerateMiss routines:
// The return address is in lr.
Isolate* isolate = masm->isolate();

Could it be that the magic instruction is messing up the return
address for that call? My goal is to analyze system behavior when
handling the IC misses, so thats why I placed the instrumentation
there. I could move the instrumentation calls up 1 level or somewhere
else you recommend so that I can enable/disable logging.

Malek

On Thu, Feb 26, 2015 at 4:10 PM, Rodolph Perfetta

Rodolph Perfetta

unread,
Feb 26, 2015, 6:57:23 PM2/26/15
to v8-u...@googlegroups.com
So m5_enableDebugFlag is a function which contains your special instruction followed by a mov pc, lr (standard return). I can see two issues:
 * your special instruction change lr where the return address is stored so your function will not return where it should. This is likely the cause for your crash
 * You are instrumenting the compilation process not the generated code which was your goal if I understood correctly.

Rodolph.

Malek Musleh

unread,
Feb 27, 2015, 10:36:48 AM2/27/15
to v8-u...@googlegroups.com
Yes, that sounds correct.
It seems that I should be

1) instrumenting the generated code, or at least have
2) the magic instruction be generated along with the rest of the generated code.

I tried to move up the call one level to CallIC::handleMiss in
v8/src/ic/ic.cc, but that causes a seg fault (rather than an illegal
instruction).

Does 1) or 2) sound right, and if so can you suggest how to do it?


On Thu, Feb 26, 2015 at 6:57 PM, Rodolph Perfetta

Rodolph Perfetta

unread,
Feb 27, 2015, 11:28:22 AM2/27/15
to v8-u...@googlegroups.com
Your instrumentation function will likely crash wherever you call it from. The issue is that you cannot thrash lr at random as it likely contains the return address of your function.

Once you fixed your magic instruction behaviour, the simplest way to add an instruction in the emitted code is to call "__ dd(the_encoding_of_your_magic_instruction);". You sometime need to be careful where to add those instructions, for example in pieces of code where the literal pool is block (BlockConstPool...). Running your code in debug mode should help you find potential issues.

Finally if you are only interested in tracking the jitted code, modifying the built-in simulator (src/arm/simulator-arm.*) is probably easier.

Rodolph.

Malek Musleh

unread,
Feb 27, 2015, 11:43:46 AM2/27/15
to v8-u...@googlegroups.com
I'll focus on using the built in v8 simulator. I'm primarily
interested in the instruction trace of the runtime when handling an IC
miss. Can you specify how I can see the arm dissembly produced by the
arm simulator?
You said the arm simulator gets built automatically when not running
on an arm host (e.g. x86-64 bit).

My host is x86-64, so I build the native version. Through the help
messages, I can see options for tracing within the simulator, but
which option actually tells it to actually use it.

../out/native/d8 --trace_sim run-deltablue.js

Rodolph Perfetta

unread,
Feb 27, 2015, 12:01:39 PM2/27/15
to v8-u...@googlegroups.com
If you are using release d8 then you need to add the disassembler to get the trace. make arm.release disassembler=on

Malek Musleh

unread,
Feb 27, 2015, 5:19:14 PM2/27/15
to v8-u...@googlegroups.com
ok, that works for seeing the native dissambly.

1)
But how do I enable use of the arm simulator? I see simulator related
options (.e.g --trace_sim) but that doesn't seem to do anything in
terms of simulating the program execution under an arm platform.

2) Is it possible to see the assembly code for routines LoadIC_Miss?
In the snippet below, I see the jump to LoadIC_Miss section, but I
don't see the dissambly for it.

kind = LOAD_IC
major_key = <NoCache>Stub
ic_state = MONOMORPHIC
extra_ic_state = 0
type = FAST
name = length
Instructions (size = 38)
0x314104fd1aa0 0 f6c201 testb rdx,0x1
0x314104fd1aa3 3 0f8418000000 jz 33 (0x314104fd1ac1)
0x314104fd1aa9 9 488b42ff REX.W movq rax,[rdx-0x1]
0x314104fd1aad 13 48bbe1866b4635200000 REX.W movq
rbx,0x2035466b86e1 ;; object: 0x20
35466b86e1 WeakCell for 0x365bbba0e011 <Map(elements=4)>
0x314104fd1ab7 23 483b4307 REX.W cmpq rax,[rbx+0x7]
0x314104fd1abb 27 0f847f2df4ff jz 0x314104f14840 ;; code:
HANDLER, LoadFieldStu
b, minor: 2051
0x314104fd1ac1 33 e91ad8f4ff jmp LoadIC_Miss (0x314104f1f2e0)
;; code: BUILTIN

On Fri, Feb 27, 2015 at 12:01 PM, Rodolph Perfetta

Jakob Kummerow

unread,
Feb 27, 2015, 7:11:26 PM2/27/15
to v8-u...@googlegroups.com
On Fri, Feb 27, 2015 at 11:19 PM, Malek Musleh <malek....@gmail.com> wrote:
ok, that works for seeing the native dissambly.

1)
But how do I enable use of the arm simulator? I see simulator related
options (.e.g --trace_sim) but that doesn't seem to do anything in
terms of simulating the program execution under an arm platform.

Have you built V8 for ARM as Rodolph told you? Try out/arm.release/d8 --trace-sim.
 
2) Is it possible to see the assembly code for routines LoadIC_Miss?

Have you considered using a debugger? It allows you to step through code, or to print stuff. Here's the LoadIC_Miss builtin (pointer addresses will be different on every run, obviously):

...
0x222959361575    53  e9a63afcff     jmp LoadIC_Miss  (0x222959325020)    ;; code: BUILTIN
...
(gdb) p v8::internal::Isolate::Current()->FindCodeObject((v8::internal::Address)0x222959325020)->Print()
0x222959324fc1: [Code]
kind = BUILTIN
Instructions (size = 24)
0x222959325020     0  5b             pop rbx
0x222959325021     1  52             push rdx
0x222959325022     2  51             push rcx
0x222959325023     3  53             push rbx
0x222959325024     4  b802000000     movl rax,0x2
0x222959325029     9  48bb709fca0000000000 REX.W movq rbx,0xca9f70    ;; external reference (IC::LoadIC_Miss)
0x222959325033    19  e9c810feff     jmp 0x222959306100      ;; code: STUB, CEntryStub, minor: 0

Reply all
Reply to author
Forward
0 new messages