only consider ptr type if not root
diff --git a/feature_reflect.go b/feature_reflect.go
index 94d8c29..8458d30 100644
--- a/feature_reflect.go
+++ b/feature_reflect.go
@@ -333,56 +333,10 @@
 	if typ.AssignableTo(jsoniterNumberType) {
 		return &jsoniterNumberCodec{}
 	}
-	if typ == marshalerType {
-		checkIsEmpty := createCheckIsEmpty(cfg, typ)
-		var encoder ValEncoder = &directMarshalerEncoder{
-			checkIsEmpty:      checkIsEmpty,
-		}
+	encoder := createEncoderOfMarshaler(cfg, prefix, typ)
+	if encoder != nil {
 		return encoder
 	}
-	if typ.Implements(marshalerType) {
-		checkIsEmpty := createCheckIsEmpty(cfg, typ)
-		var encoder ValEncoder = &marshalerEncoder{
-			valType: reflect2.Type2(typ),
-			checkIsEmpty:      checkIsEmpty,
-		}
-		return encoder
-	}
-	ptrType := reflect.PtrTo(typ)
-	if ptrType.Implements(marshalerType) {
-		checkIsEmpty := createCheckIsEmpty(cfg, ptrType)
-		var encoder ValEncoder = &marshalerEncoder{
-			valType: reflect2.Type2(ptrType),
-			checkIsEmpty:      checkIsEmpty,
-		}
-		return &referenceEncoder{encoder}
-	}
-	if typ == textMarshalerType {
-		checkIsEmpty := createCheckIsEmpty(cfg, typ)
-		var encoder ValEncoder = &directTextMarshalerEncoder{
-			checkIsEmpty:      checkIsEmpty,
-			stringEncoder: cfg.EncoderOf(reflect.TypeOf("")),
-		}
-		return encoder
-	}
-	if typ.Implements(textMarshalerType) {
-		checkIsEmpty := createCheckIsEmpty(cfg, typ)
-		var encoder ValEncoder = &textMarshalerEncoder{
-			valType: reflect2.Type2(typ),
-			stringEncoder: cfg.EncoderOf(reflect.TypeOf("")),
-			checkIsEmpty:      checkIsEmpty,
-		}
-		return encoder
-	}
-	if typ.Kind() == reflect.Map && ptrType.Implements(textMarshalerType) {
-		checkIsEmpty := createCheckIsEmpty(cfg, ptrType)
-		var encoder ValEncoder = &textMarshalerEncoder{
-			valType: reflect2.Type2(ptrType),
-			stringEncoder: cfg.EncoderOf(reflect.TypeOf("")),
-			checkIsEmpty:      checkIsEmpty,
-		}
-		return &referenceEncoder{encoder}
-	}
 	if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
 		return &base64Codec{}
 	}
diff --git a/feature_reflect_marshaler.go b/feature_reflect_marshaler.go
index 56c93d3..b3a1dcf 100644
--- a/feature_reflect_marshaler.go
+++ b/feature_reflect_marshaler.go
@@ -5,8 +5,64 @@
 	"unsafe"
 	"encoding"
 	"encoding/json"
+	"reflect"
 )
 
+func createEncoderOfMarshaler(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
+	if typ == marshalerType {
+		checkIsEmpty := createCheckIsEmpty(cfg, typ)
+		var encoder ValEncoder = &directMarshalerEncoder{
+			checkIsEmpty: checkIsEmpty,
+		}
+		return encoder
+	}
+	if typ.Implements(marshalerType) {
+		checkIsEmpty := createCheckIsEmpty(cfg, typ)
+		var encoder ValEncoder = &marshalerEncoder{
+			valType:      reflect2.Type2(typ),
+			checkIsEmpty: checkIsEmpty,
+		}
+		return encoder
+	}
+	ptrType := reflect.PtrTo(typ)
+	if prefix != "" && ptrType.Implements(marshalerType) {
+		checkIsEmpty := createCheckIsEmpty(cfg, ptrType)
+		var encoder ValEncoder = &marshalerEncoder{
+			valType:      reflect2.Type2(ptrType),
+			checkIsEmpty: checkIsEmpty,
+		}
+		return &referenceEncoder{encoder}
+	}
+	if typ == textMarshalerType {
+		checkIsEmpty := createCheckIsEmpty(cfg, typ)
+		var encoder ValEncoder = &directTextMarshalerEncoder{
+			checkIsEmpty:  checkIsEmpty,
+			stringEncoder: cfg.EncoderOf(reflect.TypeOf("")),
+		}
+		return encoder
+	}
+	if typ.Implements(textMarshalerType) {
+		checkIsEmpty := createCheckIsEmpty(cfg, typ)
+		var encoder ValEncoder = &textMarshalerEncoder{
+			valType:       reflect2.Type2(typ),
+			stringEncoder: cfg.EncoderOf(reflect.TypeOf("")),
+			checkIsEmpty:  checkIsEmpty,
+		}
+		return encoder
+	}
+	// if prefix is empty, the type is the root type
+	if prefix != "" && ptrType.Implements(textMarshalerType) {
+		checkIsEmpty := createCheckIsEmpty(cfg, ptrType)
+		var encoder ValEncoder = &textMarshalerEncoder{
+			valType:       reflect2.Type2(ptrType),
+			stringEncoder: cfg.EncoderOf(reflect.TypeOf("")),
+			checkIsEmpty:  checkIsEmpty,
+		}
+		return &referenceEncoder{encoder}
+	}
+	return nil
+}
+
 type marshalerEncoder struct {
 	checkIsEmpty checkIsEmpty
 	valType      reflect2.Type
@@ -54,9 +110,9 @@
 }
 
 type textMarshalerEncoder struct {
-	valType			reflect2.Type
-	stringEncoder   ValEncoder
-	checkIsEmpty      checkIsEmpty
+	valType       reflect2.Type
+	stringEncoder ValEncoder
+	checkIsEmpty  checkIsEmpty
 }
 
 func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
@@ -81,7 +137,7 @@
 
 type directTextMarshalerEncoder struct {
 	stringEncoder ValEncoder
-	checkIsEmpty checkIsEmpty
+	checkIsEmpty  checkIsEmpty
 }
 
 func (encoder *directTextMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {