Ejemplo n.º 1
0
Archivo: main.c Proyecto: jw3/jbmcgi
/* main output routine... */
int dooutput(lpPointBlankRange pointblankrange, int error)
{
  if (error) posterr_error(error, (error > 0) ? errors_pbr[error] : NULL);
  else
  {
    html_cgitext();
    setup_openhead();
    setup_body();
    setup_info(PBR_VERSION);
    setup_header(2);
    html_horzrule(NULL, 0, 0, 0, 0);

    writedata(pointblankrange);

    html_horzrule(NULL, 0, 0, 0, 0);

    writetable(pointblankrange);

    html_closebody();
    html_closehead();

  }
  return 0;
}
Ejemplo n.º 2
0
Archivo: ics.cpp Proyecto: jmgc/pyston
RuntimeIC::RuntimeIC(void* func_addr, int num_slots, int slot_size) : eh_frame(RUNTIMEICS_OMIT_FRAME_PTR) {
    static StatCounter sc("runtime_ics_num");
    sc.log();

    if (ENABLE_RUNTIME_ICS) {
        assert(SCRATCH_BYTES >= 0);
        assert(SCRATCH_BYTES < 0x80); // This would break both the instruction encoding and the dwarf encoding
        assert(SCRATCH_BYTES % 8 == 0);

#if RUNTIMEICS_OMIT_FRAME_PTR
        /*
         * prologue:
         * sub $0x28, %rsp  # 48 83 ec 28
         *
         * epilogue:
         * add $0x28, %rsp  # 48 83 c4 28
         * retq             # c3
         *
         */
        static const int PROLOGUE_SIZE = 4;
        static const int EPILOGUE_SIZE = 5;
        assert(SCRATCH_BYTES % 16 == 8);
#else
        /*
         * The prologue looks like:
         * push %rbp        # 55
         * mov %rsp, %rbp   # 48 89 e5
         * sub $0x30, %rsp  # 48 83 ec 30
         *
         * The epilogue is:
         * add $0x30, %rsp  # 48 83 c4 30
         * pop %rbp         # 5d
         * retq             # c3
         */
        static const int PROLOGUE_SIZE = 8;
        static const int EPILOGUE_SIZE = 6;
        assert(SCRATCH_BYTES % 16 == 0);
#endif
        static const int CALL_SIZE = 13;

        int patchable_size = num_slots * slot_size;

#ifdef NVALGRIND
        int total_size = PROLOGUE_SIZE + patchable_size + CALL_SIZE + EPILOGUE_SIZE;
        addr = malloc(total_size);
#else
        total_size = PROLOGUE_SIZE + patchable_size + CALL_SIZE + EPILOGUE_SIZE;
        addr = mmap(NULL, (total_size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1), PROT_READ | PROT_WRITE | PROT_EXEC,
                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
        RELEASE_ASSERT(addr != MAP_FAILED, "");
#endif

        // printf("Allocated runtime IC at %p\n", addr);

        std::unique_ptr<ICSetupInfo> setup_info(
            ICSetupInfo::initialize(true, num_slots, slot_size, ICSetupInfo::Generic, NULL));
        uint8_t* pp_start = (uint8_t*)addr + PROLOGUE_SIZE;
        uint8_t* pp_end = pp_start + patchable_size + CALL_SIZE;


        SpillMap _spill_map;
        PatchpointInitializationInfo initialization_info
            = initializePatchpoint3(func_addr, pp_start, pp_end, 0 /* scratch_offset */, 0 /* scratch_size */,
                                    std::unordered_set<int>(), _spill_map);
        assert(_spill_map.size() == 0);
        assert(initialization_info.slowpath_start == pp_start + patchable_size);
        assert(initialization_info.slowpath_rtn_addr == pp_end);
        assert(initialization_info.continue_addr == pp_end);

        StackInfo stack_info(SCRATCH_BYTES, 0);
        icinfo = registerCompiledPatchpoint(pp_start, pp_start + patchable_size, pp_end, pp_end, setup_info.get(),
                                            stack_info, std::unordered_set<int>());

        assembler::Assembler prologue_assem((uint8_t*)addr, PROLOGUE_SIZE);
#if RUNTIMEICS_OMIT_FRAME_PTR
        // If SCRATCH_BYTES is 8 or less, we could use more compact instruction encodings
        // (push instead of sub), but it doesn't seem worth it for now.
        prologue_assem.sub(assembler::Immediate(SCRATCH_BYTES), assembler::RSP);
#else
        prologue_assem.push(assembler::RBP);
        prologue_assem.mov(assembler::RSP, assembler::RBP);
        prologue_assem.sub(assembler::Immediate(SCRATCH_BYTES), assembler::RSP);
#endif
        assert(!prologue_assem.hasFailed());
        assert(prologue_assem.isExactlyFull());

        assembler::Assembler epilogue_assem(pp_end, EPILOGUE_SIZE);
#if RUNTIMEICS_OMIT_FRAME_PTR
        epilogue_assem.add(assembler::Immediate(SCRATCH_BYTES), assembler::RSP);
#else
        epilogue_assem.add(assembler::Immediate(SCRATCH_BYTES), assembler::RSP);
        epilogue_assem.pop(assembler::RBP);
#endif
        epilogue_assem.retq();
        assert(!epilogue_assem.hasFailed());
        assert(epilogue_assem.isExactlyFull());

        // TODO: ideally would be more intelligent about allocation strategies.
        // The code sections should be together and the eh sections together
        eh_frame.writeAndRegister(addr, total_size);
    } else {
        addr = func_addr;
    }
}
Ejemplo n.º 3
0
RuntimeIC::RuntimeIC(void* func_addr, int total_size) {
    static StatCounter sc("num_runtime_ics");
    sc.log();

    if (ENABLE_RUNTIME_ICS) {
        assert(SCRATCH_BYTES >= 0);
        assert(SCRATCH_BYTES < 0x80); // This would break both the instruction encoding and the dwarf encoding
        assert(SCRATCH_BYTES % 8 == 0);

#if RUNTIMEICS_OMIT_FRAME_PTR
        /*
         * prologue:
         * sub $0x28, %rsp  # 48 83 ec 28
         *
         * epilogue:
         * add $0x28, %rsp  # 48 83 c4 28
         * retq             # c3
         *
         */
        static const int PROLOGUE_SIZE = 4;
        static const int EPILOGUE_SIZE = 5;
        assert(SCRATCH_BYTES % 16 == 8);
#else
        /*
         * The prologue looks like:
         * push %rbp        # 55
         * mov %rsp, %rbp   # 48 89 e5
         * sub $0x30, %rsp  # 48 83 ec 30
         *
         * The epilogue is:
         * add $0x30, %rsp  # 48 83 c4 30
         * pop %rbp         # 5d
         * retq             # c3
         */
        static const int PROLOGUE_SIZE = 8;
        static const int EPILOGUE_SIZE = 6;
        assert(SCRATCH_BYTES % 16 == 0);
#endif
        static const int CALL_SIZE = 13;

        int total_code_size = total_size - EH_FRAME_SIZE;
        int patchable_size = total_code_size - (PROLOGUE_SIZE + CALL_SIZE + EPILOGUE_SIZE);

        int total_size = total_code_size + EH_FRAME_SIZE;
        assert(total_size == 512 && "we currently only have a 512 byte block memory manager");
        addr = memory_manager_512b.alloc();

        // the memory block contains the EH frame directly followed by the generated machine code.
        void* eh_frame_addr = addr;
        addr = (char*)addr + EH_FRAME_SIZE;

        // printf("Allocated runtime IC at %p\n", addr);

        std::unique_ptr<ICSetupInfo> setup_info(ICSetupInfo::initialize(true, patchable_size, ICSetupInfo::Generic));
        uint8_t* pp_start = (uint8_t*)addr + PROLOGUE_SIZE;
        uint8_t* pp_end = pp_start + patchable_size + CALL_SIZE;


        SpillMap _spill_map;
        PatchpointInitializationInfo initialization_info = initializePatchpoint3(
            func_addr, pp_start, pp_end, 0 /* scratch_offset */, 0 /* scratch_size */, LiveOutSet(), _spill_map);
        assert(_spill_map.size() == 0);
        assert(initialization_info.slowpath_start == pp_start + patchable_size);
        assert(initialization_info.slowpath_rtn_addr == pp_end);
        assert(initialization_info.continue_addr == pp_end);

        StackInfo stack_info(SCRATCH_BYTES, 0);
        icinfo = registerCompiledPatchpoint(pp_start, pp_start + patchable_size, pp_end, pp_end, setup_info.get(),
                                            stack_info, LiveOutSet());

        assembler::Assembler prologue_assem((uint8_t*)addr, PROLOGUE_SIZE);
#if RUNTIMEICS_OMIT_FRAME_PTR
        // If SCRATCH_BYTES is 8 or less, we could use more compact instruction encodings
        // (push instead of sub), but it doesn't seem worth it for now.
        prologue_assem.sub(assembler::Immediate(SCRATCH_BYTES), assembler::RSP);
#else
        prologue_assem.push(assembler::RBP);
        prologue_assem.mov(assembler::RSP, assembler::RBP);
        prologue_assem.sub(assembler::Immediate(SCRATCH_BYTES), assembler::RSP);
#endif
        assert(!prologue_assem.hasFailed());
        assert(prologue_assem.isExactlyFull());

        assembler::Assembler epilogue_assem(pp_end, EPILOGUE_SIZE);
#if RUNTIMEICS_OMIT_FRAME_PTR
        epilogue_assem.add(assembler::Immediate(SCRATCH_BYTES), assembler::RSP);
#else
        epilogue_assem.add(assembler::Immediate(SCRATCH_BYTES), assembler::RSP);
        epilogue_assem.pop(assembler::RBP);
#endif
        epilogue_assem.retq();
        assert(!epilogue_assem.hasFailed());
        assert(epilogue_assem.isExactlyFull());


        if (RUNTIMEICS_OMIT_FRAME_PTR)
            memcpy(eh_frame_addr, _eh_frame_template_ofp, _eh_frame_template_ofp_size);
        else
            memcpy(eh_frame_addr, _eh_frame_template_fp, _eh_frame_template_fp_size);
        register_eh_frame.updateAndRegisterFrameFromTemplate((uint64_t)addr, total_code_size, (uint64_t)eh_frame_addr,
                                                             EH_FRAME_SIZE);
    } else {
        addr = func_addr;
    }
}
Ejemplo n.º 4
0
void JitFragmentWriter::_emitPPCall(RewriterVar* result, void* func_addr, const RewriterVar::SmallVector& args,
                                    int num_slots, int slot_size) {
    assembler::Register r = allocReg(assembler::R11);

    if (args.size() > 6) { // only 6 args can get passed in registers.
        assert(args.size() <= 6 + JitCodeBlock::num_stack_args);
        for (int i = 6; i < args.size(); ++i) {
            assembler::Register reg = args[i]->getInReg(Location::any(), true);
            assembler->mov(reg, assembler::Indirect(assembler::RSP, sizeof(void*) * (i - 6)));
        }
        RewriterVar::SmallVector reg_args(args.begin(), args.begin() + 6);
        assert(reg_args.size() == 6);
        _setupCall(false, reg_args, RewriterVar::SmallVector());
    } else
        _setupCall(false, args, RewriterVar::SmallVector());

    if (failed)
        return;

    // make sure setupCall doesn't use R11
    assert(vars_by_location.count(assembler::R11) == 0);

    int pp_size = slot_size * num_slots;

    // make space for patchpoint
    uint8_t* pp_start = rewrite->getSlotStart() + assembler->bytesWritten();
    constexpr int call_size = 16;
    assembler->skipBytes(pp_size + call_size);
    uint8_t* pp_end = rewrite->getSlotStart() + assembler->bytesWritten();
    assert(assembler->hasFailed() || (pp_start + pp_size + call_size == pp_end));

    std::unique_ptr<ICSetupInfo> setup_info(
        ICSetupInfo::initialize(true, num_slots, slot_size, ICSetupInfo::Generic, NULL));

    // calculate available scratch space
    int pp_scratch_size = 0;
    int pp_scratch_location = rewrite->getScratchRspOffset() + rewrite->getScratchSize();
    for (int i = rewrite->getScratchSize() - 8; i >= 0; i -= 8) {
        Location l(Location::Scratch, i);
        if (vars_by_location.count(l))
            break;

        pp_scratch_size += 8;
        pp_scratch_location -= 8;
    }

    for (RewriterVar* arg : args) {
        arg->bumpUse();
    }

    assertConsistent();

    StackInfo stack_info(pp_scratch_size, pp_scratch_location);
    pp_infos.emplace_back(PPInfo{ func_addr, pp_start, pp_end, std::move(setup_info), stack_info });

    assert(vars_by_location.count(assembler::RAX) == 0);
    result->initializeInReg(assembler::RAX);
    assertConsistent();

    result->releaseIfNoUses();
}