Example #1
0
RawLocation::Actions 
RawLocation::do_conform_to(int my_index, RawLocation* other, int other_index, 
                           RawLocation::Actions allowed_actions) {
  // make sure object registers and locations have object values 
  if (other->stack_type() == T_OBJECT && stack_type() != T_OBJECT) {
    // Conformance code makes it so that this is no longer necessary.
    SHOULD_NOT_REACH_HERE();

#if NOT_CURRENTLY_USED
    // if we clear an cached object location there's no need to clear
    // any registers, since the register cache (due to type conflicts) is 
    // guaranteed never to be used again
    if (other.is_flushed() || other.is_cached()) {
      code_generator()->clear_object_location(index());
    } else {
      GUARANTEE(other.is_changed(), "only case left");
      Value other_value(other.type());
      other.read_value(other_value);
      Oop::Raw null_obj;      
      code_generator()->move(other_value, &null_obj);
    }
    return;
#endif
  }
  // compute the merge action
  const Actions required_actions = merge_actions(other);

  const Actions actions = required_actions & allowed_actions;

  // handle loads/stores from/to locations
  if (actions & LOC_LOAD)  {
    other->update_cache(other_index);
  }
  if (actions & LOC_STORE) {
    write_changes(my_index);
  }
  
  // handle register stores
  if (actions & REG_STORE && other->in_register()) {
    // declare & read values for both source and destination
    const Value this_value (this,  my_index   );
    const Value other_value(other, other_index);

    // do the register store 
    if (!other->is_register_identical_to(my_index, this, other_index)) {
      code_generator()->move(other_value, this_value);
    }
  }

  return required_actions & ~allowed_actions;
}
Example #2
0
bool RawLocation::has_register_conflict_with(int my_index,
                                             VirtualStackFrame *other_frame,
                                             RawLocation* other_loc,
                                             int other_index) {
  // locations not in registers cannot cause register conflicts
  if (!in_register()) {
    return false;
  }

  // compute the merge action
  const int actions = merge_actions(other_loc);

  if (actions & (REG_STORE | LOC_STORE)) {
    const Value this_value(this, my_index);
    if( is_used_in(other_frame, this_value) &&
        ( (actions & LOC_STORE) ||
          !is_register_identical_to(my_index, other_loc, other_index) ) ) {
      return true;
    }
  }  

  // no conflict
  return false;
}
Example #3
0
File: main.c Project: udomsak/isync
static void
sync_chans( main_vars_t *mvars, int ent )
{
	group_conf_t *group;
	channel_conf_t *chan;
	store_t *store;
	string_list_t *mbox, *sbox, **mboxp, **sboxp;
	char *channame;
	int t;

	if (!mvars->cben)
		return;
	switch (ent) {
	case E_OPEN: goto opened;
	case E_SYNC: goto syncone;
	}
	for (;;) {
		mvars->boxlist = 0;
		if (!mvars->all) {
			if (mvars->chanptr)
				channame = mvars->chanptr->string;
			else {
				for (group = groups; group; group = group->next)
					if (!strcmp( group->name, mvars->argv[mvars->oind] )) {
						mvars->chanptr = group->channels;
						channame = mvars->chanptr->string;
						goto gotgrp;
					}
				channame = mvars->argv[mvars->oind];
			  gotgrp: ;
			}
			if ((mvars->boxlist = strchr( channame, ':' )))
				*mvars->boxlist++ = 0;
			for (chan = channels; chan; chan = chan->next)
				if (!strcmp( chan->name, channame ))
					goto gotchan;
			error( "No channel or group named '%s' defined.\n", channame );
			mvars->ret = 1;
			goto gotnone;
		  gotchan:
			mvars->chan = chan;
		}
		merge_actions( mvars->chan, mvars->ops, XOP_HAVE_TYPE, OP_MASK_TYPE, OP_MASK_TYPE );
		merge_actions( mvars->chan, mvars->ops, XOP_HAVE_CREATE, OP_CREATE, 0 );
		merge_actions( mvars->chan, mvars->ops, XOP_HAVE_EXPUNGE, OP_EXPUNGE, 0 );

		mvars->state[M] = mvars->state[S] = ST_FRESH;
		info( "Channel %s\n", mvars->chan->name );
		mvars->boxes[M] = mvars->boxes[S] = mvars->cboxes = 0;
		mvars->skip = mvars->cben = 0;
		for (t = 0; t < 2; t++) {
			mvars->drv[t] = mvars->chan->stores[t]->driver;
			if ((store = mvars->drv[t]->own_store( mvars->chan->stores[t] )))
				store_opened( store, AUX );
		}
		for (t = 0; t < 2 && !mvars->skip; t++)
			if (mvars->state[t] == ST_FRESH) {
				info( "Opening %s %s...\n", str_ms[t], mvars->chan->stores[t]->name );
				mvars->drv[t]->open_store( mvars->chan->stores[t], store_opened, AUX );
			}
		mvars->cben = 1;
	  opened:
		if (mvars->skip)
			goto next;
		if (mvars->state[M] != ST_OPEN || mvars->state[S] != ST_OPEN)
			return;

		if (mvars->boxlist)
			mvars->boxp = mvars->boxlist;
		else if (mvars->chan->patterns) {
			mvars->boxes[M] = filter_boxes( mvars->ctx[M]->boxes, mvars->chan->patterns );
			mvars->boxes[S] = filter_boxes( mvars->ctx[S]->boxes, mvars->chan->patterns );
			for (mboxp = &mvars->boxes[M]; (mbox = *mboxp); ) {
				for (sboxp = &mvars->boxes[S]; (sbox = *sboxp); sboxp = &sbox->next)
					if (!strcmp( sbox->string, mbox->string )) {
						*sboxp = sbox->next;
						free( sbox );
						*mboxp = mbox->next;
						mbox->next = mvars->cboxes;
						mvars->cboxes = mbox;
						goto gotdupe;
					}
				mboxp = &mbox->next;
			  gotdupe: ;
			}
		}

		if (mvars->list && mvars->multiple)
			printf( "%s:\n", mvars->chan->name );
	  syncml:
		mvars->done = mvars->cben = 0;
	  syncmlx:
		if (mvars->boxlist) {
			if ((mvars->names[S] = strsep( &mvars->boxp, ",\n" ))) {
				if (!*mvars->names[S])
					mvars->names[S] = 0;
				if (!mvars->list) {
					mvars->names[M] = mvars->names[S];
					sync_boxes( mvars->ctx, mvars->names, mvars->chan, done_sync, mvars );
					goto syncw;
				}
				puts( nz( mvars->names[S], "INBOX" ) );
				goto syncmlx;
			}
		} else if (mvars->chan->patterns) {
			if ((mbox = mvars->cboxes)) {
				mvars->cboxes = mbox->next;
				if (!mvars->list) {
					mvars->names[M] = mvars->names[S] = mbox->string;
					sync_boxes( mvars->ctx, mvars->names, mvars->chan, done_sync_dyn, mvars );
					goto syncw;
				}
				puts( mbox->string );
				free( mbox );
				goto syncmlx;
			}
			for (t = 0; t < 2; t++)
				if ((mbox = mvars->boxes[t])) {
					mvars->boxes[t] = mbox->next;
					if ((mvars->chan->ops[1-t] & OP_MASK_TYPE) && (mvars->chan->ops[1-t] & OP_CREATE)) {
						if (!mvars->list) {
							mvars->names[M] = mvars->names[S] = mbox->string;
							sync_boxes( mvars->ctx, mvars->names, mvars->chan, done_sync_dyn, mvars );
							goto syncw;
						}
						puts( mbox->string );
					}
					free( mbox );
					goto syncmlx;
				}
		} else {
			if (!mvars->list) {
				sync_boxes( mvars->ctx, mvars->chan->boxes, mvars->chan, done_sync, mvars );
				mvars->skip = 1;
			  syncw:
				mvars->cben = 1;
				if (!mvars->done)
					return;
			  syncone:
				if (!mvars->skip)
					goto syncml;
			} else
				printf( "%s <=> %s\n", nz( mvars->chan->boxes[M], "INBOX" ), nz( mvars->chan->boxes[S], "INBOX" ) );
		}

	  next:
		for (t = 0; t < 2; t++)
			if (mvars->state[t] == ST_OPEN) {
				mvars->drv[t]->disown_store( mvars->ctx[t] );
				mvars->state[t] = ST_CLOSED;
			}
		if (mvars->state[M] != ST_CLOSED || mvars->state[S] != ST_CLOSED) {
			mvars->skip = mvars->cben = 1;
			return;
		}
		free_string_list( mvars->cboxes );
		free_string_list( mvars->boxes[M] );
		free_string_list( mvars->boxes[S] );
		if (mvars->all) {
			if (!(mvars->chan = mvars->chan->next))
				break;
		} else {
			if (mvars->chanptr && (mvars->chanptr = mvars->chanptr->next))
				continue;
		  gotnone:
			if (!mvars->argv[++mvars->oind])
				break;
		}
	}
	for (t = 0; t < N_DRIVERS; t++)
		drivers[t]->cleanup();
}