farmerjohngit / myblog

有深度的Java技术博客
1.83k stars 286 forks source link

为什么一开始就要分配lock record,lock record不是在轻量级锁才会使用吗 #29

Closed Berries-Wang closed 2 years ago

Berries-Wang commented 3 years ago

hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp:

CASE(_monitorenter) : {
        oop lockee = STACK_OBJECT(-1);
        // derefing's lockee ought to provoke implicit null check
        CHECK_NULL(lockee);
        // find a free monitor or one already allocated for this object
        // if we find a matching object then we need a new monitor
        // since this is recursive enter
        BasicObjectLock *limit = istate->monitor_base();
        BasicObjectLock *most_recent = (BasicObjectLock *)istate->stack_base();
        BasicObjectLock *entry = NULL;
        while (most_recent != limit) {
          if (most_recent->obj() == NULL)
            entry = most_recent;
          else if (most_recent->obj() == lockee)
            break;
          most_recent++;
        }

        if (entry != NULL) {
          entry->set_obj(lockee);
          int success = false;
          uintptr_t epoch_mask_in_place =
              (uintptr_t)markOopDesc::epoch_mask_in_place;

          markOop mark = lockee->mark();
          intptr_t hash = (intptr_t)markOopDesc::no_hash;
      // 余下代码省略
Parker1995 commented 2 years ago

不是的,偏向锁、重量级锁都会有这个。对于偏向锁来说,进行偏向撤销的时候,这个Lock Record可以用来帮助虚拟机,判断偏向线程是否还在同步代码块中执行。因为Lock Record的obj指针在执行到monitorenter指令进行加锁时会指向偏向锁对象,而在偏向线程执行到monitorexit指令离开同步代码块时,就会断开obj指针。 并且在锁膨胀的时候,也需要用到Lock Record,因为轻量级锁表示锁重入的方式,就是通过一个个Displaced Mark Word为NULL的Lock Record来展现的。