/* A couple ways to speed this up: - inline push_constituents - Cache the stack pointer, stack bottom, and stack limit in register variables to avoid the loads and stores; compiler is unlikely to do this. - Back-to-back push/pop pairs, like when pushing the car of a pair and then looping around to pop it again can be joined. */ static void mark_from_stack( msgc_context_t *context ) { word w; word first = (word)context->lowest_heap_address; word *bitmap = context->bitmap; int traced=0, marked=0, words_marked=0; bool already_marked; while (! context->signal_stop) { /* Pop */ if (context->stack.stkp == context->stack.stkbot) /* Stack underflow */ if (!pop_segment( &context->stack )) { if (fill_from_los_stack( context )) continue; else break; } w = *--context->stack.stkp; traced++; /* Mark */ already_marked = my_mark_object( context, w ); if (already_marked) continue; marked++; words_marked += push_constituents( context, w ); } context->traced += traced; context->marked += marked; context->words_marked += words_marked; }
/* A couple ways to speed this up: - inline push_constituents - Cache the stack pointer, stack bottom, and stack limit in register variables to avoid the loads and stores; compiler is unlikely to do this. - Back-to-back push/pop pairs, like when pushing the car of a pair and then looping around to pop it again can be joined. */ static void mark_from_stack( msgc_context_t *context ) { word w, bit_idx, word_idx, bit; word first = (word)context->lowest_heap_address; word *bitmap = context->bitmap; int traced=0, marked=0, words_marked=0; while (1) { /* Pop */ if (context->stack.stkp == context->stack.stkbot) /* Stack underflow */ if (!pop_segment( &context->stack )) if (fill_from_los_stack( context )) continue; else break; w = *--context->stack.stkp; traced++; /* Mark */ /* Note: marks object only, not entire address range occupied by object. A "real" collector must mark the range. */ bit_idx = (w - first) >> BIT_IDX_SHIFT; word_idx = bit_idx >> BITS_TO_WORDS; bit = 1 << (bit_idx & BIT_IN_WORD_MASK); if (bitmap[ word_idx ] & bit) continue; /* Already marked */ bitmap[ word_idx ] |= bit; marked++; words_marked += push_constituents( context, w ); } context->traced += traced; context->marked += marked; context->words_marked += words_marked; }
/* * === FUNCTION ====================================================================== * Name: uri_merge_paths * Description: This a attempt at implementing RFC3986 section 5.2.3. * * If the base URI has a defined authority component and an empty * path, then return a string consisting of "/" concatenated with the * reference's path; otherwise, * * return a string consisting of the reference's path component * appended to all but the last segment of the base URI's path (i.e., * excluding any characters after the right-most "/" in the base URI * path, or excluding the entire base URI path if it does not contain * any "/" characters). * * ===================================================================================== */ extern char * uri_merge_paths( uriobj_t *base, uriobj_t *rel) { char *path, *bpath = *(base->uri_path), *rpath = *(rel->uri_path); int len = 0; if( base->uri_auth && !(bpath) ) { if( !(rpath)){ path = strdup("/"); } else { len = strlen(rpath) + 2; path = (char *) malloc(len * sizeof(char)); path[0] = '/'; path[1] = '\0'; strncat(path,rpath,BUFSIZ); } } else { pop_segment(&bpath); len = strlen(rpath) + strlen(bpath) + 1; path = (char *) malloc(len * sizeof(char)); strncat(path, bpath, BUFSIZ); strncat(path, strdup("/"), BUFSIZ); strncat(path, rpath, BUFSIZ); } return path; }
E Stack<E, F>::pop() { assert(!is_empty(), "popping from an empty stack"); if (this->_cur_seg_size == 1) { E tmp = _cur_seg[--this->_cur_seg_size]; pop_segment(); return tmp; } return this->_cur_seg[--this->_cur_seg_size]; }
/* * === FUNCTION ====================================================================== * Name: uri_remove_dot_segments * Description: Implements RFC 3986 section 5.2.4 * use for interpreting and removing the special "." and ".." complete * path segments from a referenced path. This is done after the path is * extracted from a reference, whether or not the path was relative, in * order to remove any invalid or extraneous dot-segments prior to * forming the target URI. Although there are many ways to accomplish * this removal process, we describe a simple method using two string * buffers. * * ===================================================================================== */ extern char * uri_remove_dot_segments( char **path ) { char *ou_buffer = NULL, *in_buffer = NULL, *segment = NULL, sl = '\0'; int len = 0; if( *(path) == NULL ) { return NULL; } in_buffer = strdup( *(path)); len = strlen( in_buffer ) + 1; ou_buffer = (char *) malloc( len ); ou_buffer[0] = '\0'; while( in_buffer != NULL ){ segment = get_next_segment( &in_buffer); if( strcmp( segment, "../") == 0 || strcmp(segment,"./") == 0){ shift_segment( &in_buffer, 0); } else if( strcmp(segment, "/./") == 0 || strcmp(segment,"/.") == 0){ replace_prefix( &in_buffer); } else if( strcmp( segment,"/../") == 0 || strcmp(segment,"/..") == 0){ replace_prefix(&in_buffer); pop_segment(&ou_buffer); } else if( strcmp( in_buffer, ".") == 0 || strcmp( in_buffer, "..") == 0){ in_buffer = NULL; } else if( segment) { sl = segment[ strlen(segment) - 1]; if( sl == '/'){ segment = shift_segment(&in_buffer, 0); } else { segment = shift_segment(&in_buffer, 1); } strcat(ou_buffer, segment); } } len = strlen(ou_buffer) + 1; realloc( (void *) ou_buffer, len); return ou_buffer; }
static bool fill_from_los_stack( msgc_context_t *context ) { int next, k, n, i; word obj; if (context->los_stack.stkp == context->los_stack.stkbot) { /* underflow */ if (!pop_segment( &context->los_stack )) return FALSE; } obj = *--context->los_stack.stkp; next = (int)*--context->los_stack.stkp; n = bytes2words( sizefield( *ptrof(obj) ) ); k = min( n-next, LARGE_OBJECT_LIMIT ); for ( i=0 ; i < k ; i++ ) PUSH( context, vector_ref( obj, i+next ) ); if (next+k < n) LOS_PUSH( context, next+k, obj ); return TRUE; }