Makes LengthFieldBasedFrameDecoder::decode inlineable
Motivation: The decode method is too large to be inlined with default compiler settings, hence the uncommon paths need to be packed and moved away form the common one. Modifications: The uncommon paths of the decode call (eg failures with thrown exceptions) are packed and moved in private methods in order to reduce the size of the common one and let it being inlined. Result: The decode method is being inlined if the stack depth allows it.
This commit is contained in:
parent
0b0de76adc
commit
6780183a89
@ -15,13 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec;
|
package io.netty.handler.codec;
|
||||||
|
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.serialization.ObjectDecoder;
|
import io.netty.handler.codec.serialization.ObjectDecoder;
|
||||||
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A decoder that splits the received {@link ByteBuf}s dynamically by the
|
* A decoder that splits the received {@link ByteBuf}s dynamically by the
|
||||||
* value of the length field in the message. It is particularly useful when you
|
* value of the length field in the message. It is particularly useful when you
|
||||||
@ -346,16 +346,7 @@ public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void discardingTooLongFrame(ByteBuf in) {
|
||||||
* Create a frame out of the {@link ByteBuf} and return it.
|
|
||||||
*
|
|
||||||
* @param ctx the {@link ChannelHandlerContext} which this {@link ByteToMessageDecoder} belongs to
|
|
||||||
* @param in the {@link ByteBuf} from which to read data
|
|
||||||
* @return frame the {@link ByteBuf} which represent the frame or {@code null} if no frame could
|
|
||||||
* be created.
|
|
||||||
*/
|
|
||||||
protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
|
|
||||||
if (discardingTooLongFrame) {
|
|
||||||
long bytesToDiscard = this.bytesToDiscard;
|
long bytesToDiscard = this.bytesToDiscard;
|
||||||
int localBytesToDiscard = (int) Math.min(bytesToDiscard, in.readableBytes());
|
int localBytesToDiscard = (int) Math.min(bytesToDiscard, in.readableBytes());
|
||||||
in.skipBytes(localBytesToDiscard);
|
in.skipBytes(localBytesToDiscard);
|
||||||
@ -365,29 +356,22 @@ public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder {
|
|||||||
failIfNecessary(false);
|
failIfNecessary(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in.readableBytes() < lengthFieldEndOffset) {
|
private static void failOnNegativeLengthField(ByteBuf in, long frameLength, int lengthFieldEndOffset) {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int actualLengthFieldOffset = in.readerIndex() + lengthFieldOffset;
|
|
||||||
long frameLength = getUnadjustedFrameLength(in, actualLengthFieldOffset, lengthFieldLength, byteOrder);
|
|
||||||
|
|
||||||
if (frameLength < 0) {
|
|
||||||
in.skipBytes(lengthFieldEndOffset);
|
in.skipBytes(lengthFieldEndOffset);
|
||||||
throw new CorruptedFrameException(
|
throw new CorruptedFrameException(
|
||||||
"negative pre-adjustment length field: " + frameLength);
|
"negative pre-adjustment length field: " + frameLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
frameLength += lengthAdjustment + lengthFieldEndOffset;
|
private static void failOnFrameLengthLessThanLengthFieldEndOffset(ByteBuf in,
|
||||||
|
long frameLength,
|
||||||
if (frameLength < lengthFieldEndOffset) {
|
int lengthFieldEndOffset) {
|
||||||
in.skipBytes(lengthFieldEndOffset);
|
in.skipBytes(lengthFieldEndOffset);
|
||||||
throw new CorruptedFrameException(
|
throw new CorruptedFrameException(
|
||||||
"Adjusted frame length (" + frameLength + ") is less " +
|
"Adjusted frame length (" + frameLength + ") is less " +
|
||||||
"than lengthFieldEndOffset: " + lengthFieldEndOffset);
|
"than lengthFieldEndOffset: " + lengthFieldEndOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frameLength > maxFrameLength) {
|
private void exceededFrameLength(ByteBuf in, long frameLength) {
|
||||||
long discard = frameLength - in.readableBytes();
|
long discard = frameLength - in.readableBytes();
|
||||||
tooLongFrameLength = frameLength;
|
tooLongFrameLength = frameLength;
|
||||||
|
|
||||||
@ -401,6 +385,49 @@ public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder {
|
|||||||
in.skipBytes(in.readableBytes());
|
in.skipBytes(in.readableBytes());
|
||||||
}
|
}
|
||||||
failIfNecessary(true);
|
failIfNecessary(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void failOnFrameLengthLessThanInitialBytesToStrip(ByteBuf in,
|
||||||
|
long frameLength,
|
||||||
|
int initialBytesToStrip) {
|
||||||
|
in.skipBytes((int) frameLength);
|
||||||
|
throw new CorruptedFrameException(
|
||||||
|
"Adjusted frame length (" + frameLength + ") is less " +
|
||||||
|
"than initialBytesToStrip: " + initialBytesToStrip);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a frame out of the {@link ByteBuf} and return it.
|
||||||
|
*
|
||||||
|
* @param ctx the {@link ChannelHandlerContext} which this {@link ByteToMessageDecoder} belongs to
|
||||||
|
* @param in the {@link ByteBuf} from which to read data
|
||||||
|
* @return frame the {@link ByteBuf} which represent the frame or {@code null} if no frame could
|
||||||
|
* be created.
|
||||||
|
*/
|
||||||
|
protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
|
||||||
|
if (discardingTooLongFrame) {
|
||||||
|
discardingTooLongFrame(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in.readableBytes() < lengthFieldEndOffset) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int actualLengthFieldOffset = in.readerIndex() + lengthFieldOffset;
|
||||||
|
long frameLength = getUnadjustedFrameLength(in, actualLengthFieldOffset, lengthFieldLength, byteOrder);
|
||||||
|
|
||||||
|
if (frameLength < 0) {
|
||||||
|
failOnNegativeLengthField(in, frameLength, lengthFieldEndOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
frameLength += lengthAdjustment + lengthFieldEndOffset;
|
||||||
|
|
||||||
|
if (frameLength < lengthFieldEndOffset) {
|
||||||
|
failOnFrameLengthLessThanLengthFieldEndOffset(in, frameLength, lengthFieldEndOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frameLength > maxFrameLength) {
|
||||||
|
exceededFrameLength(in, frameLength);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,10 +438,7 @@ public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (initialBytesToStrip > frameLengthInt) {
|
if (initialBytesToStrip > frameLengthInt) {
|
||||||
in.skipBytes(frameLengthInt);
|
failOnFrameLengthLessThanInitialBytesToStrip(in, frameLength, initialBytesToStrip);
|
||||||
throw new CorruptedFrameException(
|
|
||||||
"Adjusted frame length (" + frameLength + ") is less " +
|
|
||||||
"than initialBytesToStrip: " + initialBytesToStrip);
|
|
||||||
}
|
}
|
||||||
in.skipBytes(initialBytesToStrip);
|
in.skipBytes(initialBytesToStrip);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user