Use -fvisibility and clean up a little.
The visibility change isn't obviously useful, but it's a good excuse to clean
up some of our networking code a little.
Change-Id: I165b32b9c76a3707c512e07de07992f63673ab4f
diff --git a/NativeCode.mk b/NativeCode.mk
index d4960c5..648cd33 100644
--- a/NativeCode.mk
+++ b/NativeCode.mk
@@ -78,6 +78,8 @@
core_c_includes := $(sort libcore/include $(LOCAL_C_INCLUDES) $(JNI_H_INCLUDE))
core_shared_libraries := $(sort $(LOCAL_SHARED_LIBRARIES))
core_static_libraries := $(sort $(LOCAL_STATIC_LIBRARIES))
+core_cflags := -fvisibility=hidden -fvisibility-inlines-hidden
+core_cflags += '-DGCC_HIDDEN=__attribute__((visibility("hidden")))'
#
@@ -87,7 +89,7 @@
include $(CLEAR_VARS)
LOCAL_CFLAGS += -Wall -Wextra -Werror
-
+LOCAL_CFLAGS += $(core_cflags)
ifeq ($(TARGET_ARCH),arm)
# Ignore "note: the mangling of 'va_list' has changed in GCC 4.4"
LOCAL_CFLAGS += -Wno-psabi
@@ -125,6 +127,7 @@
# Define the rules.
LOCAL_SRC_FILES := $(core_src_files)
+ LOCAL_CFLAGS += $(core_cflags)
LOCAL_C_INCLUDES := $(core_c_includes)
LOCAL_SHARED_LIBRARIES := $(core_shared_libraries)
LOCAL_STATIC_LIBRARIES := $(core_static_libraries)
diff --git a/dalvik/src/main/java/dalvik/system/BlockGuard.java b/dalvik/src/main/java/dalvik/system/BlockGuard.java
index 9b9268d..0f7ff10 100644
--- a/dalvik/src/main/java/dalvik/system/BlockGuard.java
+++ b/dalvik/src/main/java/dalvik/system/BlockGuard.java
@@ -404,10 +404,6 @@
mNetwork.close(aFD);
}
- public void setInetAddress(InetAddress sender, byte[] address) {
- mNetwork.setInetAddress(sender, address);
- }
-
private boolean isLingerSocket(FileDescriptor fd) throws SocketException {
try {
Object lingerValue = mNetwork.getSocketOption(fd, SocketOptions.SO_LINGER);
diff --git a/luni/src/main/java/java/net/PlainDatagramSocketImpl.java b/luni/src/main/java/java/net/PlainDatagramSocketImpl.java
index d28ac1f..1109a0e 100644
--- a/luni/src/main/java/java/net/PlainDatagramSocketImpl.java
+++ b/luni/src/main/java/java/net/PlainDatagramSocketImpl.java
@@ -155,7 +155,8 @@
// We don't actually want the data: we just want the DatagramPacket's filled-in address.
DatagramPacket packet = new DatagramPacket(EmptyArray.BYTE, 0);
int result = peekData(packet);
- Platform.NETWORK.setInetAddress(sender, packet.getAddress().getAddress());
+ // TODO: maybe recv should do this?
+ sender.ipaddress = packet.getAddress().getAddress();
return result;
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
index c073c41..3cf4549 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
@@ -141,8 +141,4 @@
* concurrently.
*/
public void close(FileDescriptor fd) throws IOException;
-
- // TODO: change the single caller so that recv/recvDirect
- // can mutate the InetAddress as a side-effect.
- public void setInetAddress(InetAddress sender, byte[] address);
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
index 4be00f2..6ff29c6 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
@@ -101,8 +101,6 @@
public native void sendUrgentData(FileDescriptor fd, byte value);
- public native void setInetAddress(InetAddress sender, byte[] address);
-
public native void setSocketOption(FileDescriptor fd, int opt, Object optVal)
throws SocketException;
diff --git a/luni/src/main/native/libcore_net_RawSocket.cpp b/luni/src/main/native/libcore_net_RawSocket.cpp
index 7878986..b23208d 100644
--- a/luni/src/main/native/libcore_net_RawSocket.cpp
+++ b/luni/src/main/native/libcore_net_RawSocket.cpp
@@ -39,6 +39,11 @@
#include <netinet/ip.h>
#include <linux/udp.h>
+union GCC_HIDDEN sockunion {
+ sockaddr sa;
+ sockaddr_ll sll;
+} su;
+
/*
* Creates a socket suitable for raw socket operations. The socket is
* bound to the interface specified by the supplied name. The socket
@@ -51,24 +56,19 @@
static void RawSocket_create(JNIEnv* env, jclass, jobject fileDescriptor,
jstring interfaceName) {
- union sockunion {
- struct sockaddr sa;
- struct sockaddr_ll sll;
- } su;
-
- short protocol = ETH_P_IP;
ScopedUtfChars ifname(env, interfaceName);
-
if (ifname.c_str() == NULL) {
return;
}
+ short protocol = ETH_P_IP;
+ sockunion su;
memset(&su, 0, sizeof(su));
su.sll.sll_family = PF_PACKET;
su.sll.sll_protocol = htons(protocol);
su.sll.sll_ifindex = if_nametoindex(ifname.c_str());
- int sock = socket(PF_PACKET, SOCK_DGRAM, htons(protocol));
+ int sock = socket(PF_PACKET, SOCK_DGRAM, htons(protocol));
if (sock == -1) {
LOGE("Can't create socket %s", strerror(errno));
jniThrowSocketException(env, errno);
@@ -76,7 +76,6 @@
}
jniSetFileDescriptorOfFD(env, fileDescriptor, sock);
-
if (!setBlocking(sock, false)) {
LOGE("Can't set non-blocking mode on socket %s", strerror(errno));
jniThrowSocketException(env, errno);
@@ -84,7 +83,6 @@
}
int err = bind(sock, &su.sa, sizeof(su));
-
if (err != 0) {
LOGE("Socket bind error %s", strerror(errno));
jniThrowSocketException(env, errno);
@@ -108,29 +106,23 @@
return 0;
}
- union sockunion {
- struct sockaddr sa;
- struct sockaddr_ll sll;
- } su;
- short protocol = ETH_P_IP;
ScopedUtfChars ifname(env, interfaceName);
-
if (ifname.c_str() == NULL) {
return 0;
}
ScopedByteArrayRO byteArray(env, packet);
-
if (byteArray.get() == NULL) {
return 0;
}
ScopedByteArrayRO mac(env, destMac);
-
if (mac.get() == NULL) {
return 0;
}
+ short protocol = ETH_P_IP;
+ sockunion su;
memset(&su, 0, sizeof(su));
su.sll.sll_hatype = htons(1); // ARPHRD_ETHER
su.sll.sll_halen = mac.size();
@@ -140,7 +132,6 @@
su.sll.sll_ifindex = if_nametoindex(ifname.c_str());
int err;
-
{
int intFd = fd.get();
AsynchronousSocketCloseMonitor monitor(intFd);
@@ -163,33 +154,29 @@
jint timeout_millis)
{
NetFd fd(env, fileDescriptor);
-
if (fd.isClosed()) {
return 0;
}
ScopedByteArrayRW body(env, packet);
jbyte* packetData = body.get();
-
if (packetData == NULL) {
return 0;
}
packetData += offset;
- int packetSize = byteCount;
- unsigned int size = 0;
- struct pollfd fds[1];
-
+ pollfd fds[1];
fds[0].fd = fd.get();
fds[0].events = POLLIN;
int retval = poll(fds, 1, timeout_millis);
-
if (retval <= 0) {
return 0;
}
+ unsigned int size = 0;
{
+ int packetSize = byteCount;
int intFd = fd.get();
AsynchronousSocketCloseMonitor monitor(intFd);
size = NET_FAILURE_RETRY(fd, read(intFd, packetData, packetSize));
@@ -201,20 +188,16 @@
// quick check for UDP type & UDP port
// the packet is an IP header, UDP header, and UDP payload
- if ((size < (sizeof(struct iphdr) + sizeof(struct udphdr)))) {
+ if ((size < (sizeof(iphdr) + sizeof(udphdr)))) {
return 0; // runt packet
}
- u_int8_t ip_proto = ((struct iphdr *) packetData)->protocol;
-
+ u_int8_t ip_proto = ((iphdr *) packetData)->protocol;
if (ip_proto != IPPROTO_UDP) {
return 0; // something other than UDP
}
- __be16 destPort =
- htons((reinterpret_cast<struct udphdr*>
- (packetData + sizeof(struct iphdr)))->dest);
-
+ __be16 destPort = htons((reinterpret_cast<udphdr*>(packetData + sizeof(iphdr)))->dest);
if (destPort != port) {
return 0; // something other than requested port
}
@@ -222,19 +205,12 @@
return size;
}
-/*
- * JNI registration
- */
static JNINativeMethod gRawMethods[] = {
- NATIVE_METHOD(RawSocket, create,
- "(Ljava/io/FileDescriptor;Ljava/lang/String;)V"),
- NATIVE_METHOD(RawSocket, sendPacket,
- "(Ljava/io/FileDescriptor;Ljava/lang/String;[B[BII)I"),
- NATIVE_METHOD(RawSocket, recvPacket,
- "(Ljava/io/FileDescriptor;[BIIII)I"),
+ NATIVE_METHOD(RawSocket, create, "(Ljava/io/FileDescriptor;Ljava/lang/String;)V"),
+ NATIVE_METHOD(RawSocket, sendPacket, "(Ljava/io/FileDescriptor;Ljava/lang/String;[B[BII)I"),
+ NATIVE_METHOD(RawSocket, recvPacket, "(Ljava/io/FileDescriptor;[BIIII)I"),
};
int register_libcore_net_RawSocket(JNIEnv* env) {
- return jniRegisterNativeMethods(env,
- "libcore/net/RawSocket", gRawMethods, NELEM(gRawMethods));
+ return jniRegisterNativeMethods(env, "libcore/net/RawSocket", gRawMethods, NELEM(gRawMethods));
}
diff --git a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
index 03d1e69..9e5e69f 100644
--- a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
+++ b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
@@ -81,18 +81,6 @@
#define SOCKET_OP_READ 1
#define SOCKET_OP_WRITE 2
-static struct CachedFields {
- jfieldID iaddr_ipaddress;
- jfieldID integer_class_value;
- jfieldID boolean_class_value;
- jfieldID socketimpl_address;
- jfieldID socketimpl_port;
- jfieldID socketimpl_localport;
- jfieldID dpack_address;
- jfieldID dpack_port;
- jfieldID dpack_length;
-} gCachedFields;
-
/**
* Returns the port number in a sockaddr_storage structure.
*
@@ -203,10 +191,8 @@
jniThrowNullPointerException(env, NULL);
return false;
}
- jbyteArray addressBytes =
- reinterpret_cast<jbyteArray>(env->GetObjectField(inetAddress,
- gCachedFields.iaddr_ipaddress));
-
+ static jfieldID fid = env->GetFieldID(JniConstants::inetAddressClass, "ipaddress", "[B");
+ jbyteArray addressBytes = reinterpret_cast<jbyteArray>(env->GetObjectField(inetAddress, fid));
return byteArrayToSocketAddress(env, NULL, addressBytes, port, ss);
}
@@ -379,7 +365,7 @@
if (rc == -1 && errno == EINVAL) {
// Maybe we're a 32-bit binary talking to a 64-bit kernel?
// glibc doesn't automatically handle this.
- struct group_req64 {
+ struct GCC_HIDDEN group_req64 {
uint32_t gr_interface;
uint32_t my_padding;
sockaddr_storage gr_group;
@@ -396,34 +382,6 @@
}
#endif // def ENABLE_MULTICAST
-static bool initCachedFields(JNIEnv* env) {
- memset(&gCachedFields, 0, sizeof(gCachedFields));
- struct CachedFields* c = &gCachedFields;
-
- struct fieldInfo {
- jfieldID* field;
- jclass clazz;
- const char* name;
- const char* type;
- } fields[] = {
- {&c->iaddr_ipaddress, JniConstants::inetAddressClass, "ipaddress", "[B"},
- {&c->integer_class_value, JniConstants::integerClass, "value", "I"},
- {&c->boolean_class_value, JniConstants::booleanClass, "value", "Z"},
- {&c->socketimpl_port, JniConstants::socketImplClass, "port", "I"},
- {&c->socketimpl_localport, JniConstants::socketImplClass, "localport", "I"},
- {&c->socketimpl_address, JniConstants::socketImplClass, "address", "Ljava/net/InetAddress;"},
- {&c->dpack_address, JniConstants::datagramPacketClass, "address", "Ljava/net/InetAddress;"},
- {&c->dpack_port, JniConstants::datagramPacketClass, "port", "I"},
- {&c->dpack_length, JniConstants::datagramPacketClass, "length", "I"}
- };
- for (unsigned i = 0; i < sizeof(fields) / sizeof(fields[0]); i++) {
- fieldInfo f = fields[i];
- *f.field = env->GetFieldID(f.clazz, f.name, f.type);
- if (*f.field == NULL) return false;
- }
- return true;
-}
-
static void OSNetworkSystem_socket(JNIEnv* env, jobject, jobject fileDescriptor, jboolean stream) {
if (fileDescriptor == NULL) {
jniThrowNullPointerException(env, NULL);
@@ -670,8 +628,6 @@
return;
}
int remotePort = getSocketAddressPort(&ss);
- env->SetObjectField(newSocket, gCachedFields.socketimpl_address, remoteAddress);
- env->SetIntField(newSocket, gCachedFields.socketimpl_port, remotePort);
// Local port.
memset(&ss, 0, addrLen);
@@ -682,7 +638,13 @@
return;
}
int localPort = getSocketAddressPort(&ss);
- env->SetIntField(newSocket, gCachedFields.socketimpl_localport, localPort);
+
+ static jfieldID addressFid = env->GetFieldID(JniConstants::socketImplClass, "address", "Ljava/net/InetAddress;");
+ static jfieldID localPortFid = env->GetFieldID(JniConstants::socketImplClass, "localport", "I");
+ static jfieldID portFid = env->GetFieldID(JniConstants::socketImplClass, "port", "I");
+ env->SetObjectField(newSocket, addressFid, remoteAddress);
+ env->SetIntField(newSocket, portFid, remotePort);
+ env->SetIntField(newSocket, localPortFid, localPort);
}
jniSetFileDescriptorOfFD(env, clientFileDescriptor, clientFd);
@@ -719,11 +681,6 @@
}
}
-static void OSNetworkSystem_setInetAddress(JNIEnv* env, jobject,
- jobject sender, jbyteArray address) {
- env->SetObjectField(sender, gCachedFields.iaddr_ipaddress, address);
-}
-
// TODO: can we merge this with recvDirect?
static jint OSNetworkSystem_readDirect(JNIEnv* env, jobject, jobject fileDescriptor,
jint address, jint count) {
@@ -804,8 +761,11 @@
return 0;
}
+ static jfieldID addressFid = env->GetFieldID(JniConstants::datagramPacketClass, "address", "Ljava/net/InetAddress;");
+ static jfieldID lengthFid = env->GetFieldID(JniConstants::datagramPacketClass, "length", "I");
+ static jfieldID portFid = env->GetFieldID(JniConstants::datagramPacketClass, "port", "I");
if (packet != NULL) {
- env->SetIntField(packet, gCachedFields.dpack_length, bytesReceived);
+ env->SetIntField(packet, lengthFid, bytesReceived);
if (!connected) {
jbyteArray addr = socketAddressToByteArray(env, &ss);
if (addr == NULL) {
@@ -816,8 +776,8 @@
if (sender == NULL) {
return 0;
}
- env->SetObjectField(packet, gCachedFields.dpack_address, sender);
- env->SetIntField(packet, gCachedFields.dpack_port, port);
+ env->SetObjectField(packet, addressFid, sender);
+ env->SetIntField(packet, portFid, port);
}
}
return bytesReceived;
@@ -1182,9 +1142,9 @@
int intVal;
bool wasBoolean = false;
if (env->IsInstanceOf(optVal, JniConstants::integerClass)) {
- intVal = (int) env->GetIntField(optVal, gCachedFields.integer_class_value);
+ intVal = intValue(env, optVal);
} else if (env->IsInstanceOf(optVal, JniConstants::booleanClass)) {
- intVal = (int) env->GetBooleanField(optVal, gCachedFields.boolean_class_value);
+ intVal = (int) booleanValue(env, optVal);
wasBoolean = true;
} else if (env->IsInstanceOf(optVal, JniConstants::inetAddressClass)) {
// We use optVal directly as an InetAddress for IP_MULTICAST_IF.
@@ -1391,7 +1351,6 @@
NATIVE_METHOD(OSNetworkSystem, send, "(Ljava/io/FileDescriptor;[BIIILjava/net/InetAddress;)I"),
NATIVE_METHOD(OSNetworkSystem, sendDirect, "(Ljava/io/FileDescriptor;IIIILjava/net/InetAddress;)I"),
NATIVE_METHOD(OSNetworkSystem, sendUrgentData, "(Ljava/io/FileDescriptor;B)V"),
- NATIVE_METHOD(OSNetworkSystem, setInetAddress, "(Ljava/net/InetAddress;[B)V"),
NATIVE_METHOD(OSNetworkSystem, setSocketOption, "(Ljava/io/FileDescriptor;ILjava/lang/Object;)V"),
NATIVE_METHOD(OSNetworkSystem, shutdownInput, "(Ljava/io/FileDescriptor;)V"),
NATIVE_METHOD(OSNetworkSystem, shutdownOutput, "(Ljava/io/FileDescriptor;)V"),
@@ -1402,6 +1361,5 @@
int register_org_apache_harmony_luni_platform_OSNetworkSystem(JNIEnv* env) {
AsynchronousSocketCloseMonitor::init();
- return initCachedFields(env) && jniRegisterNativeMethods(env,
- "org/apache/harmony/luni/platform/OSNetworkSystem", gMethods, NELEM(gMethods));
+ return jniRegisterNativeMethods(env, "org/apache/harmony/luni/platform/OSNetworkSystem", gMethods, NELEM(gMethods));
}
diff --git a/luni/src/main/native/valueOf.cpp b/luni/src/main/native/valueOf.cpp
index a3475e3..310d48c 100644
--- a/luni/src/main/native/valueOf.cpp
+++ b/luni/src/main/native/valueOf.cpp
@@ -41,3 +41,13 @@
jobject longValueOf(JNIEnv* env, jlong value) {
return valueOf(env, JniConstants::longClass, "(J)Ljava/lang/Long;", value);
}
+
+jboolean booleanValue(JNIEnv* env, jobject javaLangBoolean) {
+ static jfieldID fid = env->GetFieldID(JniConstants::booleanClass, "value", "Z");
+ return env->GetBooleanField(javaLangBoolean, fid);
+}
+
+jint intValue(JNIEnv* env, jobject javaLangInteger) {
+ static jfieldID fid = env->GetFieldID(JniConstants::integerClass, "value", "I");
+ return env->GetIntField(javaLangInteger, fid);
+}
diff --git a/luni/src/main/native/valueOf.h b/luni/src/main/native/valueOf.h
index 5c8588f..592977d 100644
--- a/luni/src/main/native/valueOf.h
+++ b/luni/src/main/native/valueOf.h
@@ -24,4 +24,9 @@
jobject integerValueOf(JNIEnv* env, jint i);
jobject longValueOf(JNIEnv* env, jlong l);
+// Note that these aren't equivalent to the Number methods: the jobject MUST be of the exact
+// type specified. This is less general but faster (and currently sufficient).
+jboolean booleanValue(JNIEnv* env, jobject javaLangBoolean);
+jint intValue(JNIEnv* env, jobject javaLangInteger);
+
#endif // VALUE_OF_H_included