Ejemplo n.º 1
0
static volatile int read_kernel_memory(long offset, int virtualized, int size) {
    int result;
    map_offset(offset, virtualized);
    int scaled_offset = (offset-(offset&~0xFFFF));
    if(size==1)
        result = mem_8[scaled_offset/sizeof(char)];
    else if(size==2)
        result = mem_16[scaled_offset/sizeof(short)];
    else
        result = mem_32[scaled_offset/sizeof(long)];

    return result;
}
Ejemplo n.º 2
0
Label* CacheStub::prologue(bool immediateOnly) {
  assert(((Float_Tag | Int_Tag) & Mem_Tag) == 0, "tagging scheme changed");
  Label* miss = NULL;
  Label* loadMapAfterHandlingImmediates = NULL;
  pc_t floatAddr, smiAddr;
  computeJumpAddr(nsmi, theSendDesc,   stsmi,   smiAddr);
  computeJumpAddr(nfloat, theSendDesc, stfloat, floatAddr);

  // put rcvr in Temp1
  a->movl(esp, leaf_rcvr_offset * oopSize, NumberOperand, Temp1);
  // Load map if needed
  if (immediateOnly)
    ;
  else {
    a->btl(Mem_Tag_bit_i386, Temp1);
    loadMapAfterHandlingImmediates = new Label(a->printing);
    a->jc(loadMapAfterHandlingImmediates); // jump if memOop    
  }

  if (nsmi  &&  nfloat) {
    Label* not_smi = br_if_not_smi();
    add_case(nsmi, stsmi, smiAddr);
    
    not_smi->define();
    // if immediateOnly = false and we're down here, we've already tested for memOop
    // and hence there's no need to test for the float tag.
    if (immediateOnly)
      miss = br_if_not_float(); // br if mem
    else
      miss = NULL;
    add_case(nfloat, stfloat, floatAddr);
  }
  else if (nsmi)   { miss = br_if_not_smi();    add_case(nsmi,   stsmi,     smiAddr);  }
  else if (nfloat) { miss = br_if_not_float();  add_case(nfloat, stfloat, floatAddr);  }
  else {
    // tested for Oop above, so rcvr is int or float,
    // but there are no smi or float cases, so must be a miss
    miss = new Label(a->printing);
    a->jmp(miss);
  }
  if (loadMapAfterHandlingImmediates) {
    loadMapAfterHandlingImmediates->define();
    // CacheStub::test expects Temp1 to contain the receiver's map
    a->movl(Temp1, map_offset(), NumberOperand, Temp1);
  }
  return miss;
}
Ejemplo n.º 3
0
fint CodeGen::verifyParents(objectLookupTarget* target, Location t, fint count) {
  
  
  a.Comment("verify");
  assert(target->links != NULL, "expecting an assignable parent link");
    
  for ( assignableSlotLink* l = target->links; ; ) {
    // load assignable parent slot value
    a.movl(t, smiOop(l->slot->data)->byte_count() - Mem_Tag, VMAddressOperand,  Temp1);
    Label ok;
    Label miss;
    Map* targetMap = l->target->obj->map();
    
    if (l->target->value_constrained) {
      // constraint for a particular oop (ambiguity resolution)
      loadOop(Temp2, l->target->obj);         // load assumed value
      a.cmpl(Temp1, Temp2);                   // compare values
      a.je(&ok);               // will branch
    } 
    // check if map of parent is correct
    else if (targetMap == Memory->smi_map) {
      a.testl(Tag_Mask, NumberOperand, Temp1);        // test for integer tag
      a.je( &ok );                                     // branch if parent is integer
    } 
    else if (targetMap == Memory->float_map) {
      a.btl( Float_Tag_bit_i386, Temp1);
      // if bit set must be hit, otherwise is mark
      a.jc(&ok);             // branch if parent is a float
    }
    else {                                  // must be mem tag
      a.btl(Mem_Tag_bit_i386, Temp1);
      // if bit set must be hit, otherwise is mark
      a.jnc(&miss);                          // branch if parent is not mem oop

      a.movl(Temp1, map_offset(), NumberOperand, Temp2);    // load receiver map
      a.cmpl((int32)targetMap->enclosing_mapOop(), OopOperand, Temp2); // cmp to map constraint
      a.je(&ok);               // correct
    }
    
    miss.define();
    // This will be backpatched to call an nmethod, so need to leave incoming link alone.
    // Must look like the original call to me plus extra info in regs
    // Pass a link to the branch and nmln in the DILinkReg.
    a.movl(count, NumberOperand, DICountReg);  // count of parents verified
    
    // must align nmln to follow
    // There is a call coming, each 5 bytes, so want pc + 5 to be 0 mod 4.
    // See align * in asmDefs_gcc_i386.[sS]
    // get ic value to pass in, cannot use call cause of backpatching, etc.
    Label next;
    a.call(&next);
    next.define(); 

    // two tasks: compute amount to add to savedPC so it simulates a call: must point to after the jmp below
    // Also, just add enough nops so that nmln after call is word-alligned
    
    fint bytes_from_here_to_after_jmp_before_alignment = 1 /* popl */ + 3 /* addl */ + 5 /* jmp */;
    int32 here = a.offset();
    fint word_fraction_from_here_to_after_jmp_before_alignment = (here + bytes_from_here_to_after_jmp_before_alignment ) & 3;    
    fint num_nops = (BytesPerWord - word_fraction_from_here_to_after_jmp_before_alignment) & (BytesPerWord-1);
    fint bytes_from_here_to_after_jmp = bytes_from_here_to_after_jmp_before_alignment + num_nops;
    
    for (fint i = 0;  i < num_nops; ++i) a.nop();
    

    a.popl(DIInlineCacheReg); // 1 byte, prepare to calculate IC addr below
    a.addl(bytes_from_here_to_after_jmp, NumberOperand, DIInlineCacheReg);  // 3 bytes, finish calc IC addr below
    // following must be parsable to set_target_of_Self_call_site
    a.jmp( (int32)SendDIMessage_stub, DIVMAddressOperand);
    assert( a.offset() == here + bytes_from_here_to_after_jmp, "checking");
    assert((a.offset() & (BytesPerWord-1)) == 0, "must be aligned");
    a.Data(0);                                // first  part of DI nmln
    a.Data(0);                                // second part of DI nmln
    
    a.hlt();
          
    ok.define();
    
    ++count;
    if (l->target->links) count = verifyParents(l->target, Temp1, count);
    
    l = l->next;
    if (l == 0)
      break;
    // if multiple dynamic parents, reload slot holder before looping (HACK!)
    t = loadPath(Temp1, target, LReceiverReg, Temp1);
  }
  
  return count;
}
Ejemplo n.º 4
0
 fint CodeGen::verifyParents(objectLookupTarget* target, Location t,
                             fint count) {
   assignableSlotLink* l = target->links;
   assert(l != 0, "expecting an assignable parent link");
     
   for (;;) {
     a.LoadI(t, smiOop(l->slot->data)->byte_count() - Mem_Tag, Temp1);
     // load assignable parent slot value
     Label* ok;
     Map* targetMap = l->target->obj->map();
     if (l->target->value_constrained) {
       // constraint for a particular oop (ambiguity resolution)
       loadOop(Temp2, l->target->obj);         // load assumed value
       a.SubCCR(Temp1, Temp2, G0);             // compare values
       ok = a.BeqForward(false);               // branch if value OK
       if (l->target->links) a.Nop();
     } else {
       // check if map of parent is correct
       if (targetMap == Memory->smi_map) {
         a.AndCCI(Temp1, Tag_Mask, G0);        // test for integer tag
         ok = a.BeqForward(false);             // branch if parent is integer
         if (l->target->links) a.Nop();
       } else if (targetMap == Memory->float_map) {
         a.AndCCI(Temp1, Float_Tag, G0);       // test for float tag
         ok = a.BneForward(false);             // branch if parent is a float
         if (l->target->links) a.Nop();
       } else {
         Label* miss = NULL;
         if (!FastMapTest) {
           a.AndCCI(Temp1, Mem_Tag, G0);       // test for mem tag
           Label* mem = a.BneForward(true);    // branch if parent is mem oop
           a.LoadI(Temp1, map_offset(), Temp2); // load receiver map
           miss = a.BraForward(true);          // branch to diLookup section
           mem->define();
         } else {
           a.LoadI(Temp1, map_offset(), Temp2); // load receiver map
         }
         loadOop(Temp3, targetMap->enclosing_mapOop()); // load map constraint
         a.SubCCR(Temp2, Temp3, G0);   // compare w/ parent's map
         ok = a.BeqForward(false);     // correct
         if (l->target->links) a.Nop();
         if (miss) miss->define();
       }
     }
     void* addr = Memory->code->trapdoors->SendDIMessage_stub_td();
     a.SetHiD(addr, Temp1);
     a.JmpLD(Temp1, addr, DILinkReg);
     loadImmediate(DICountReg, count);         // count of parents verified
     a.Data(0);                                // first part of DI nmln
     a.Data(0);                                // second part of DI nmln
     ok->define();
     
     count ++;
     if (l->target->links) count = verifyParents(l->target, Temp1, count);
     
     l = l->next;
     if (l == 0) break;
     // if multiple dynamic parents, reload slot holder before looping (HACK!)
     t = loadPath(Temp1, target, ReceiverReg, Temp1);
   }
   
   return count;
 }
Ejemplo n.º 5
0
 fint TypeTestNode::prologue(Assembler* a, Location rcvr, fint smiIndex,
                             fint floatIndex, bool immediateOnly,
                             Label*& firstMemOopTest) {
   // handle immediate cases of type test and load map if necessary
   // smiIndex/Float are the indices of the smi/float case in the map list
   // (+ 1, so that "not present" == 0)
   // returns the index (+ 1) of the fall-through case 
   assert(((Float_Tag | Int_Tag) & Mem_Tag) == 0, "tagging scheme changed");
   assert(!immediateOnly || !needMapLoad,
          "immediateOnly implies !needMapLoad");
   fint fallThrough = 0;
   
   if (needMapLoad) {
     if (!FastMapTest || smiIndex || floatIndex) {
       a->AndCCI(rcvr, Mem_Tag, G0);
       firstMemOopTest = a->BneForward(true);
     }
     a->LoadI(rcvr, map_offset(), RcvrMapReg);
   }
   if (smiIndex) {
     a->AndCCI(rcvr, Tag_Mask, G0);
     if (SICCountTypeTests) theAssembler->doOneTypeTest();
     if (SICCountIntTagTests && immediateOnly) {
       // check if this tag test is on behalf of integer arithmetic
       methodMap* mm = (methodMap*)scope()->method()->map();
       stringOop sel = mm->get_selector_at(bci());
       bool isArith = (sel == VMString[PLUS] || sel == VMString[MINUS]);
       theAssembler->markTagTest(1, isArith);
     }
     define(smiIndex, a->BeqForward(SICCountTypeTests));
     if (SICCountTypeTests) a->endTypeTest();
     if (floatIndex) {
       a->AndCCI(rcvr, Float_Tag, G0); // test for float (delay slot)
       if (needMapLoad && !FastMapTest) {
         // already tested for memTag, so it must be a float
         fallThrough = floatIndex;
       } else {
         // need to test float tag
         // andcc rcvr, Float_Tag  (done in delay slot of prev. test)
         if (SICCountTypeTests) theAssembler->doOneTypeTest();
         define(floatIndex, a->BneForward(true));
         if (SICCountTypeTests) {
           a->endTypeTest();
         } else {
           a->Nop();       // must be here because next instr could be unimp
         }
       }
     } else {
       if (SICCountTypeTests) {
         // already filled delay slot
       } else {
         a->Nop();         // must be here because next instr could be unimp
       }
     }
   } else if (floatIndex) {
     a->AndCCI(rcvr, Float_Tag, G0); 
     if (SICCountTypeTests) theAssembler->doOneTypeTest();
     define(floatIndex, a->BneForward(true));
     if (SICCountTypeTests) {
       a->endTypeTest();   // only executed in success case
     } else {
       a->Nop();           // must be here because next instr could be unimp
     }
     // if we get here, it must be an int (if needMapLoad) or a memOop (if
     // !needMapLoad), but we didn't expect this so jump to the unknown case
     define(0, a->BraForward(!SICCountTypeTests));
     if (SICCountTypeTests) a->endTypeTest();
   } else if (needMapLoad) {
     // neither int nor float case
     assert(maps->length(), "should have at least one memOop case");
     if (FastMapTest) {
       // no test for memOop-ness, i.e. just fall through to first memOop case
     } else {
       // it's not a memOop and we have no immediate case, so jump to unknown
       assert(fallThrough == 0, "shouldn't have a fall-through");
       define(0, a->BraForward(true));
     }
   } else {
     // neither int not float nor mapLoad - empty prologue
   }
   return fallThrough;
 }
Ejemplo n.º 6
0
Label* CacheStub::prologue(bool immediateOnly) {
  // prologue:  andcc  rcvr, 1
  //  bnz,a  _mapTest
  //          load   [rcvr+map_offset], t
  // *if nsmi
  //    andcc  rcvr, Tag_Mask
  //    bne    _next
  //    <jmpl smi_addr>
  //  *if nfloat
  // next:
  //    <jmpl float_addr>
  //  *endif float
  // *else if nfloat
  //    andcc  rcvr, Float_Mask
  //    beq    _next
  //    <jmpl float_addr>
  // *endif
  // * if !(nsmi && nfloat)
  // next:
  //   nop
  //   bra,a   _miss
  // *endif
  // mapTest:  
  //  setHi  ..., t1                       (may be delay slot)
  assert(((Float_Tag | Int_Tag) & Mem_Tag) == 0, "tagging scheme changed");
  prevAddr = NULL;
  Label* result = NULL;
  Label* next = NULL;
  Label* mapTest = NULL;
  char *floatAddr, *smiAddr;
  computeJumpAddr(nsmi, theSendDesc, stsmi, smiAddr);
  computeJumpAddr(nfloat, theSendDesc, stfloat, floatAddr);
  
  if (immediateOnly)
    ;
  else if (FastMapTest  &&  nsmi == NULL  &&  nfloat == NULL)
    a->LoadI(ReceiverReg, map_offset(), Temp1);

  else {
    a->AndCCI(ReceiverReg, Mem_Tag, G0);
    mapTest = a->BneForward(true);
    a->LoadI(ReceiverReg, map_offset(), Temp1); // in delay slot, only do me if branch goes
  }
 
  if (nsmi) {
    n[newMethods] = nsmi;
    st[newMethods++] = stsmi;
    if (SICCountIntTagTests) a->markTagTest(1);
    a->AndCCI(ReceiverReg, Tag_Mask, G0);
    next = a->BneForward(true);
    a->AndCCI(ReceiverReg, Float_Tag, G0);    // test for float (delay slot)
    jump(smiAddr);
    a->Nop();
    if (nfloat) {
      n[newMethods] = nfloat;
      st[newMethods++] = stfloat;
      next->define();
      if (immediateOnly) {
        // need to test float tag (test done in delay slot of int case)
        result = a->BeqForward(false);
      } else {
        // already tested for memTag, so it must be a float
      }
      jump(floatAddr);
      a->Nop();
    } else {
      result = next;
    }
  } else if (nfloat) {
    n[newMethods] = nfloat;
    st[newMethods++] = stfloat;
    a->AndCCI(ReceiverReg, Float_Tag, G0);
    result = a->BeqForward(false);
    jump(floatAddr);
    a->Nop();
  } else {
    assert(!nsmi && !nfloat, "just checkin'");
    if (next) next->define();
    if (FastMapTest) {
      assert(!next && !mapTest, "should not be set");
    } else {
      result = a->BraForward(true);
    }
  }
  if (mapTest) mapTest->define();
  return result;
}
Ejemplo n.º 7
0
bool isMapLoad(int* instp) {
  return isLoadWord(instp) && getArithImm(instp) == map_offset();
}