Add a macro GCC_VERSION and use it to control code paths.

Code paths that work on lower version of GCC are required because
Mac OS will never move beyond GCC 4.2. I added the code paths so
that Mac builds can pass.

Change-Id: I4a3340355133dff4a5107b94970bc809d9de264e
diff --git a/src/assembler_x86.h b/src/assembler_x86.h
index b1d34d3..2f293e4 100644
--- a/src/assembler_x86.h
+++ b/src/assembler_x86.h
@@ -28,7 +28,10 @@
  private:
   const int32_t value_;
 
+  // TODO: Remove the #if when Mac OS build server no longer uses GCC 4.2.*.
+#if GCC_VERSION >= 40300
   DISALLOW_COPY_AND_ASSIGN(Immediate);
+#endif
 };
 
 
@@ -116,7 +119,10 @@
 
   friend class X86Assembler;
 
+  // TODO: Remove the #if when Mac OS build server no longer uses GCC 4.2.*.
+#if GCC_VERSION >= 40300
   DISALLOW_COPY_AND_ASSIGN(Operand);
+#endif
 };
 
 
@@ -192,7 +198,10 @@
  private:
   Address() {}
 
+  // TODO: Remove the #if when Mac OS build server no longer uses GCC 4.2.*.
+#if GCC_VERSION >= 40300
   DISALLOW_COPY_AND_ASSIGN(Address);
+#endif
 };
 
 
diff --git a/src/common_test.h b/src/common_test.h
index 396cda5..c89527c 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -173,8 +173,16 @@
     uintptr_t limit = RoundUp(data + code_length, kPageSize);
     uintptr_t len = limit - base;
     int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
+
     // Flush instruction cache
+    // Only uses __builtin___clear_cache if GCC >= 4.3.3
+#if GCC_VERSION >= 40303
     __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
+#else
+    // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
+    // need to generate clear_cache on x86.
+#endif
+
     CHECK_EQ(result, 0);
   }
 
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 597c58b..95acf99 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -126,6 +126,11 @@
   JNIEnvExt* env = reinterpret_cast<JNIEnvExt*>(public_env);
   return reinterpret_cast<T>(env->self->DecodeJObject(obj));
 }
+// TODO: Change to use template when Mac OS build server no longer uses GCC 4.2.*.
+Object* DecodeObj(JNIEnv* public_env, jobject obj) {
+  JNIEnvExt* env = reinterpret_cast<JNIEnvExt*>(public_env);
+  return reinterpret_cast<Object*>(env->self->DecodeJObject(obj));
+}
 // Explicit instantiations.
 template Array* Decode<Array*>(JNIEnv*, jobject);
 template Class* Decode<Class*>(JNIEnv*, jobject);
@@ -179,7 +184,7 @@
         offset += 4;
         break;
       case 'L': {
-        Object* obj = Decode<Object*>(env, va_arg(ap, jobject));
+        Object* obj = DecodeObj(env, va_arg(ap, jobject));
         *reinterpret_cast<Object**>(&arg_array[offset]) = obj;
         offset += sizeof(Object*);
         break;
@@ -218,7 +223,7 @@
         offset += 4;
         break;
       case 'L': {
-        Object* obj = Decode<Object*>(env, args[i - 1].l);
+        Object* obj = DecodeObj(env, args[i - 1].l);
         *reinterpret_cast<Object**>(&arg_array[offset]) = obj;
         offset += sizeof(Object*);
         break;
@@ -281,7 +286,7 @@
 
 static JValue InvokeWithVarArgs(JNIEnv* public_env, jobject obj, jmethodID mid, va_list args) {
   JNIEnvExt* env = reinterpret_cast<JNIEnvExt*>(public_env);
-  Object* receiver = Decode<Object*>(env, obj);
+  Object* receiver = DecodeObj(env, obj);
   Method* method = DecodeMethod(mid);
   UniquePtr<byte[]> arg_array(CreateArgArray(env, method, args));
   return InvokeWithArgArray(env, receiver, method, arg_array.get());
@@ -294,7 +299,7 @@
 static JValue InvokeVirtualOrInterfaceWithJValues(JNIEnv* public_env, jobject obj, jmethodID mid,
                                                   jvalue* args) {
   JNIEnvExt* env = reinterpret_cast<JNIEnvExt*>(public_env);
-  Object* receiver = Decode<Object*>(env, obj);
+  Object* receiver = DecodeObj(env, obj);
   Method* method = FindVirtualMethod(receiver, DecodeMethod(mid));
   UniquePtr<byte[]> arg_array(CreateArgArray(env, method, args));
   return InvokeWithArgArray(env, receiver, method, arg_array.get());
@@ -303,7 +308,7 @@
 static JValue InvokeVirtualOrInterfaceWithVarArgs(JNIEnv* public_env, jobject obj, jmethodID mid,
                                                   va_list args) {
   JNIEnvExt* env = reinterpret_cast<JNIEnvExt*>(public_env);
-  Object* receiver = Decode<Object*>(env, obj);
+  Object* receiver = DecodeObj(env, obj);
   Method* method = FindVirtualMethod(receiver, DecodeMethod(mid));
   UniquePtr<byte[]> arg_array(CreateArgArray(env, method, args));
   return InvokeWithArgArray(env, receiver, method, arg_array.get());
@@ -2977,7 +2982,7 @@
     os << "JNIWeakGlobalRefType";
     return os;
   default:
-    os << "jobjectRefType[" << static_cast<int>(rhs) << "]";
+    LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
     return os;
   }
 }
diff --git a/src/logging.h b/src/logging.h
index 51d4496..9e10bd9 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -191,7 +191,11 @@
 
  private:
   T& value_;
+
+// TODO: Remove the #if when Mac OS build server no longer uses GCC 4.2.*.
+#if GCC_VERSION >= 40300
   DISALLOW_COPY_AND_ASSIGN(Dumpable);
+#endif
 };
 
 template<typename T>
diff --git a/src/macros.h b/src/macros.h
index 7652f71..5b9bdb6 100644
--- a/src/macros.h
+++ b/src/macros.h
@@ -16,6 +16,10 @@
 
 #include <stddef.h>  // for size_t
 
+#define GCC_VERSION (  _GNUC_ * 10000      \
+                     + _GNUC_MINOR_ * 100  \
+                     + __GNUC_PATCHLEVEL__)
+
 // The COMPILE_ASSERT macro can be used to verify that a compile time
 // expression is true. For example, you could use it to verify the
 // size of a static array: