1// Copyright (c) 2012 The Chromium 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 5package org.chromium.tools.findbugs.plugin; 6 7import org.apache.bcel.classfile.Code; 8 9import edu.umd.cs.findbugs.BugInstance; 10import edu.umd.cs.findbugs.BugReporter; 11import edu.umd.cs.findbugs.bcel.OpcodeStackDetector; 12 13/** 14 * This class detects the synchronized(this). 15 * 16 * The pattern of byte code of synchronized(this) is 17 * aload_0 # Load the 'this' pointer on top of stack 18 * dup # Duplicate the 'this' pointer 19 * astore_x # Store this for late use, it might be astore. 20 * monitorenter 21 */ 22public class SynchronizedThisDetector extends OpcodeStackDetector { 23 private final int PATTERN[] = {ALOAD_0, DUP, 0xff, 0xff, MONITORENTER}; 24 25 private int mStep = 0; 26 private BugReporter mBugReporter; 27 28 public SynchronizedThisDetector(BugReporter bugReporter) { 29 mBugReporter = bugReporter; 30 } 31 32 @Override 33 public void visit(Code code) { 34 mStep = 0; 35 super.visit(code); 36 } 37 38 @Override 39 public void sawOpcode(int seen) { 40 if (PATTERN[mStep] == seen) { 41 mStep++; 42 if (mStep == PATTERN.length) { 43 mBugReporter.reportBug(new BugInstance(this, "CHROMIUM_SYNCHRONIZED_THIS", 44 NORMAL_PRIORITY) 45 .addClassAndMethod(this) 46 .addSourceLine(this)); 47 mStep = 0; 48 return; 49 } 50 } else if (mStep == 2) { 51 // This could be astore_x 52 switch (seen) { 53 case ASTORE_0: 54 case ASTORE_1: 55 case ASTORE_2: 56 case ASTORE_3: 57 mStep += 2; 58 break; 59 case ASTORE: 60 mStep++; 61 break; 62 default: 63 mStep = 0; 64 break; 65 } 66 } else if (mStep == 3) { 67 // Could be any byte following the ASTORE. 68 mStep++; 69 } else { 70 mStep = 0; 71 } 72 } 73} 74