| 
					
				 | 
			
			
				@@ -212,7 +212,11 @@ static uint8_t get_placement(grpc_error **err, size_t size) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_ASSERT(*err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   uint8_t slots = (uint8_t)(size / sizeof(intptr_t)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if ((*err)->arena_size + slots > (*err)->arena_capacity) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    (*err)->arena_capacity = (uint8_t)(3 * (*err)->arena_capacity / 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (*err)->arena_capacity = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (uint8_t)GPR_MIN(UINT8_MAX - 1, (3 * (*err)->arena_capacity / 2)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if ((*err)->arena_size + slots > (*err)->arena_capacity) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return UINT8_MAX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     *err = gpr_realloc( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         *err, sizeof(grpc_error) + (*err)->arena_capacity * sizeof(intptr_t)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -223,10 +227,14 @@ static uint8_t get_placement(grpc_error **err, size_t size) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void internal_set_int(grpc_error **err, grpc_error_ints which, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                              intptr_t value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // GPR_ASSERT((*err)->ints[which] == UINT8_MAX); // TODO, enforce this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   uint8_t slot = (*err)->ints[which]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (slot == UINT8_MAX) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     slot = get_placement(err, sizeof(value)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (slot == UINT8_MAX) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_log(GPR_ERROR, "Error %p is full, dropping int {\"%s\":%" PRIiPTR "}", *err, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error_int_name(which), value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   (*err)->ints[which] = slot; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   (*err)->arena[slot] = value; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -234,10 +242,16 @@ static void internal_set_int(grpc_error **err, grpc_error_ints which, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void internal_set_str(grpc_error **err, grpc_error_strs which, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                              grpc_slice value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // GPR_ASSERT((*err)->strs[which] == UINT8_MAX); // TODO, enforce this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   uint8_t slot = (*err)->strs[which]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (slot == UINT8_MAX) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     slot = get_placement(err, sizeof(value)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (slot == UINT8_MAX) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const char *str = grpc_slice_to_c_string(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_log(GPR_ERROR, "Error %p is full, dropping string {\"%s\":\"%s\"}", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              *err, error_str_name(which), str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_free((void *)str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     unref_slice(*(grpc_slice *)((*err)->arena + slot)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -245,12 +259,19 @@ static void internal_set_str(grpc_error **err, grpc_error_strs which, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   memcpy((*err)->arena + slot, &value, sizeof(value)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static char *fmt_time(gpr_timespec tm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void internal_set_time(grpc_error **err, grpc_error_times which, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                               gpr_timespec value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // GPR_ASSERT((*err)->times[which] == UINT8_MAX); // TODO, enforce this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   uint8_t slot = (*err)->times[which]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (slot == UINT8_MAX) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     slot = get_placement(err, sizeof(value)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (slot == UINT8_MAX) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const char *time_str = fmt_time(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_log(GPR_ERROR, "Error %p is full, dropping \"%s\":\"%s\"}", *err, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error_time_name(which), time_str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_free((void *)time_str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   (*err)->times[which] = slot; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   memcpy((*err)->arena + slot, &value, sizeof(value)); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -259,6 +280,12 @@ static void internal_set_time(grpc_error **err, grpc_error_times which, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void internal_add_error(grpc_error **err, grpc_error *new) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_linked_error new_last = {new, UINT8_MAX}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   uint8_t slot = get_placement(err, sizeof(grpc_linked_error)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (slot == UINT8_MAX) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gpr_log(GPR_ERROR, "Error %p is full, dropping error %p = %s", *err, new, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            grpc_error_string(new)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GRPC_ERROR_UNREF(new); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if ((*err)->first_err == UINT8_MAX) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GPR_ASSERT((*err)->last_err == UINT8_MAX); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     (*err)->last_err = slot; 
			 |