Home | History | Annotate | Download | only in cctest
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <stdlib.h>
      6 
      7 #include "src/v8.h"
      8 
      9 #include "src/debug/debug.h"
     10 #include "src/disasm.h"
     11 #include "src/disassembler.h"
     12 #include "src/ic/ic.h"
     13 #include "src/macro-assembler.h"
     14 #include "src/x87/frames-x87.h"
     15 #include "test/cctest/cctest.h"
     16 #include "test/cctest/compiler/c-signature.h"
     17 #include "test/cctest/compiler/call-tester.h"
     18 
     19 using namespace v8::internal;
     20 using namespace v8::internal::compiler;
     21 
     22 #define __ assm.
     23 
     24 static int32_t DummyStaticFunction(Object* result) { return 1; }
     25 
     26 TEST(WasmRelocationX87MemoryReference) {
     27   Isolate* isolate = CcTest::i_isolate();
     28   Zone zone(isolate->allocator());
     29   HandleScope scope(isolate);
     30   v8::internal::byte buffer[4096];
     31   Assembler assm(isolate, buffer, sizeof buffer);
     32   DummyStaticFunction(NULL);
     33   int32_t imm = 1234567;
     34 
     35   __ mov(eax, Immediate(reinterpret_cast<Address>(imm),
     36                         RelocInfo::WASM_MEMORY_REFERENCE));
     37   __ nop();
     38   __ ret(0);
     39 
     40   CSignature0<int32_t> csig;
     41   CodeDesc desc;
     42   assm.GetCode(&desc);
     43   Handle<Code> code = isolate->factory()->NewCode(
     44       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
     45   USE(code);
     46 
     47   CodeRunner<int32_t> runnable(isolate, code, &csig);
     48   int32_t ret_value = runnable.Call();
     49   CHECK_EQ(ret_value, imm);
     50 
     51 #ifdef OBJECT_PRINT
     52   OFStream os(stdout);
     53   code->Print(os);
     54   byte* begin = code->instruction_start();
     55   byte* end = begin + code->instruction_size();
     56   disasm::Disassembler::Disassemble(stdout, begin, end);
     57 #endif
     58 
     59   size_t offset = 1234;
     60 
     61   // Relocating references by offset
     62   int mode_mask = (1 << RelocInfo::WASM_MEMORY_REFERENCE);
     63   for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
     64     RelocInfo::Mode mode = it.rinfo()->rmode();
     65     if (RelocInfo::IsWasmMemoryReference(mode)) {
     66       // Dummy values of size used here as the objective of the test is to
     67       // verify that the immediate is patched correctly
     68       it.rinfo()->update_wasm_memory_reference(
     69           it.rinfo()->wasm_memory_reference(),
     70           it.rinfo()->wasm_memory_reference() + offset, 1, 2,
     71           SKIP_ICACHE_FLUSH);
     72     }
     73   }
     74 
     75   // Check if immediate is updated correctly
     76   ret_value = runnable.Call();
     77   CHECK_EQ(ret_value, imm + offset);
     78 
     79 #ifdef OBJECT_PRINT
     80   code->Print(os);
     81   begin = code->instruction_start();
     82   end = begin + code->instruction_size();
     83   disasm::Disassembler::Disassemble(stdout, begin, end);
     84 #endif
     85 }
     86 
     87 TEST(WasmRelocationX87MemorySizeReference) {
     88   CcTest::InitializeVM();
     89   Isolate* isolate = CcTest::i_isolate();
     90   Zone zone(isolate->allocator());
     91   HandleScope scope(isolate);
     92   v8::internal::byte buffer[4096];
     93   Assembler assm(isolate, buffer, sizeof buffer);
     94   DummyStaticFunction(NULL);
     95   int32_t size = 80;
     96   Label fail;
     97 
     98   __ mov(eax, Immediate(reinterpret_cast<Address>(size),
     99                         RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
    100   __ cmp(eax, Immediate(reinterpret_cast<Address>(size),
    101                         RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
    102   __ j(not_equal, &fail);
    103   __ ret(0);
    104   __ bind(&fail);
    105   __ mov(eax, 0xdeadbeef);
    106   __ ret(0);
    107 
    108   CSignature0<int32_t> csig;
    109   CodeDesc desc;
    110   assm.GetCode(&desc);
    111   Handle<Code> code = isolate->factory()->NewCode(
    112       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    113   USE(code);
    114 
    115   CodeRunner<int32_t> runnable(isolate, code, &csig);
    116   int32_t ret_value = runnable.Call();
    117   CHECK_NE(ret_value, 0xdeadbeef);
    118 
    119 #ifdef OBJECT_PRINT
    120   OFStream os(stdout);
    121   code->Print(os);
    122   byte* begin = code->instruction_start();
    123   byte* end = begin + code->instruction_size();
    124   disasm::Disassembler::Disassemble(stdout, begin, end);
    125 #endif
    126 
    127   size_t offset = 10;
    128 
    129   int mode_mask = (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
    130   for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
    131     RelocInfo::Mode mode = it.rinfo()->rmode();
    132     if (RelocInfo::IsWasmMemorySizeReference(mode)) {
    133       it.rinfo()->update_wasm_memory_reference(
    134           reinterpret_cast<Address>(1234), reinterpret_cast<Address>(1234),
    135           it.rinfo()->wasm_memory_size_reference(),
    136           it.rinfo()->wasm_memory_size_reference() + offset, SKIP_ICACHE_FLUSH);
    137     }
    138   }
    139 
    140   ret_value = runnable.Call();
    141   CHECK_NE(ret_value, 0xdeadbeef);
    142 
    143 #ifdef OBJECT_PRINT
    144   code->Print(os);
    145   begin = code->instruction_start();
    146   end = begin + code->instruction_size();
    147   disasm::Disassembler::Disassemble(stdout, begin, end);
    148 #endif
    149 }
    150 #undef __
    151