Check-in [7aed923c63]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add ATOMIC_COMPARE_SET_AND_GET; Add ability to generate atomic operations via assembly.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:7aed923c63b597b9eaa1803182ce11b7219dda5a
User & Date: stephanie.gawroriski 2019-07-01 12:24:03
Context
2019-07-01
14:51
Remove space. check-in: 6981cd552c user: stephanie.gawroriski tags: trunk
12:24
Add ATOMIC_COMPARE_SET_AND_GET; Add ability to generate atomic operations via assembly. check-in: 7aed923c63 user: stephanie.gawroriski tags: trunk
11:53
Synchronized ClassInfo. check-in: d6ba3195e8 user: stephanie.gawroriski tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ratufacoat/sjmerc.c.

172
173
174
175
176
177
178



179
180
181
182
183
184
185
....
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
....
1994
1995
1996
1997
1998
1999
2000
























2001
2002
2003
2004
2005
2006
2007
#define SJME_OP_ATOMIC_INT_DECREMENT_AND_GET UINT8_C(0xF9)

/** Atomically increments a memory address. */
#define SJME_OP_ATOMIC_INT_INCREMENT UINT8_C(0xFA)

/** System call. */
#define SJME_OP_SYSTEM_CALL UINT8_C(0xFB)




/** Load from pool, note that at code gen time this is aliased. */
#define SJME_OP_LOAD_POOL UINT8_C(0xFD)

/** Load from integer array. */
#define SJME_OP_LOAD_FROM_INTARRAY UINT8_C(0xFE)

................................................................................
sjme_jint sjme_cpuexec(sjme_jvm* jvm, sjme_cpu* cpu, sjme_error* error,
	sjme_jint cycles)
{
	sjme_jint op, enc;
	sjme_vmemptr nextpc;
	sjme_vmemptr tempp;
	sjme_jint* r;
	sjme_jint ia, ib, ic, id;
	sjme_cpustate* oldcpu;
	
	/* Invalid argument? */
	if (jvm == NULL || cpu == NULL)
	{
		sjme_seterror(error, SJME_ERROR_INVALIDARG, 0);
		
................................................................................
						fprintf(stderr, "*(%08x + %d) = r[%d] = %d/%08x\n",
							(int)tempp, (int)ib, (int)ic,
							(int)r[ic], (int)r[ic]);
#endif
					}
				}
				break;
























				
				/* Atomic decrement and get. */
			case SJME_OP_ATOMIC_INT_DECREMENT_AND_GET:
				{
					/* Target register. */
					id = sjme_opdecodereg(jvm->vmem, &nextpc, error);
					







>
>
>







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
....
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
....
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
#define SJME_OP_ATOMIC_INT_DECREMENT_AND_GET UINT8_C(0xF9)

/** Atomically increments a memory address. */
#define SJME_OP_ATOMIC_INT_INCREMENT UINT8_C(0xFA)

/** System call. */
#define SJME_OP_SYSTEM_CALL UINT8_C(0xFB)

/** Atomically checks, gets, and sets (if matched) the value. */
#define SJME_OP_ATOMIC_COMPARE_GET_AND_SET UINT8_C(0xFC)

/** Load from pool, note that at code gen time this is aliased. */
#define SJME_OP_LOAD_POOL UINT8_C(0xFD)

/** Load from integer array. */
#define SJME_OP_LOAD_FROM_INTARRAY UINT8_C(0xFE)

................................................................................
sjme_jint sjme_cpuexec(sjme_jvm* jvm, sjme_cpu* cpu, sjme_error* error,
	sjme_jint cycles)
{
	sjme_jint op, enc;
	sjme_vmemptr nextpc;
	sjme_vmemptr tempp;
	sjme_jint* r;
	sjme_jint ia, ib, ic, id, ie;
	sjme_cpustate* oldcpu;
	
	/* Invalid argument? */
	if (jvm == NULL || cpu == NULL)
	{
		sjme_seterror(error, SJME_ERROR_INVALIDARG, 0);
		
................................................................................
						fprintf(stderr, "*(%08x + %d) = r[%d] = %d/%08x\n",
							(int)tempp, (int)ib, (int)ic,
							(int)r[ic], (int)r[ic]);
#endif
					}
				}
				break;
				
				/* Atomic compare, get, and set. */
			case SJME_OP_ATOMIC_COMPARE_GET_AND_SET:
				{
					/* Check. */
					ia = r[sjme_opdecodereg(jvm->vmem, &nextpc, error)];
					
					/* Get. */
					ib = sjme_opdecodereg(jvm->vmem, &nextpc, error);
					
					/* Set. */
					ic = r[sjme_opdecodereg(jvm->vmem, &nextpc, error)];
					
					/* Address. */
					id = r[sjme_opdecodereg(jvm->vmem, &nextpc, error)];
					
					/* Offset. */
					ie = sjme_opdecodeui(jvm->vmem, &nextpc, error);
					
					/* Perform the operation. */
					r[ib] = sjme_jint sjme_vmmatomicintcheckgetandset(
						jvm->vmem, ia, ic, id, ie, error);
				}
				break;
				
				/* Atomic decrement and get. */
			case SJME_OP_ATOMIC_INT_DECREMENT_AND_GET:
				{
					/* Target register. */
					id = sjme_opdecodereg(jvm->vmem, &nextpc, error);
					

Changes to ratufacoat/sjmerc.h.

675
676
677
678
679
680
681















682
683
684
685
686
687
688
689
690
691
692
693
 * @param val The value to write.
 * @param error The error state.
 * @since 2019/06/25
 */
void sjme_vmmwritep(sjme_vmem* vmem, sjme_jint type, sjme_vmemptr* ptr,
	sjme_jint val, sjme_error* error);
















/**
 * Atomically increments and integer and then gets its value.
 *
 * @param vmem Virtual memory.
 * @param type The type to utilize.
 * @param ptr The pointer address.
 * @param off The offset.
 * @param add The value to add.
 * @param error The error state.
 * @return The value after the addition.
 * @since 2019/06/25
 */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




<







675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700

701
702
703
704
705
706
707
 * @param val The value to write.
 * @param error The error state.
 * @since 2019/06/25
 */
void sjme_vmmwritep(sjme_vmem* vmem, sjme_jint type, sjme_vmemptr* ptr,
	sjme_jint val, sjme_error* error);

/**
 * Atomically reads, checks, and then sets the value.
 *
 * @param vmem Virtual memory.
 * @param check The check value.
 * @param set The set value.
 * @param ptr The pointer address.
 * @param off The offset.
 * @param error The error state.
 * @return The value which was read.
 * @since 2019/07/01
 */
sjme_jint sjme_vmmatomicintcheckgetandset(sjme_vmem* vmem, sjme_jint check,
	sjme_jint set, sjme_vmemptr ptr, sjme_jint off, sjme_error* error);
	
/**
 * Atomically increments and integer and then gets its value.
 *
 * @param vmem Virtual memory.

 * @param ptr The pointer address.
 * @param off The offset.
 * @param add The value to add.
 * @param error The error state.
 * @return The value after the addition.
 * @since 2019/06/25
 */

Changes to ratufacoat/sjmercvm.c.

378
379
380
381
382
383
384

























385
386
387
388
389
390








391
392
393
394
395
396
397
398
399
400
401
402
403
			
		case SJME_VMMTYPE_INTEGER:
		case SJME_VMMTYPE_JAVAINTEGER:
			*ptr = *ptr + 4;
			break;
	}
}


























/** Atomically increments and integer and then gets its value. */
sjme_jint sjme_vmmatomicintaddandget(sjme_vmem* vmem,
	sjme_vmemptr ptr, sjme_jint off, sjme_jint add, sjme_error* error)
{
	sjme_jint rv;








	
	/* Read current value. */
	rv = sjme_vmmread(vmem, SJME_VMMTYPE_INTEGER, ptr, off, error);
	
	/* Add value. */
	rv += add;
	
	/* Store new value. */
	sjme_vmmwrite(vmem, SJME_VMMTYPE_INTEGER, ptr, off, rv, error);
	
	/* Return new value. */
	return rv;
}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






>
>
>
>
>
>
>
>













378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
			
		case SJME_VMMTYPE_INTEGER:
		case SJME_VMMTYPE_JAVAINTEGER:
			*ptr = *ptr + 4;
			break;
	}
}

/** Atomically reads, checks, and then sets the value. */
sjme_jint sjme_vmmatomicintcheckgetandset(sjme_vmem* vmem, sjme_jint check,
	sjme_jint set, sjme_vmemptr ptr, sjme_jint off, sjme_error* error)
{
	sjme_jint rv;
	
	/* Invalid argument? */
	if (vmem == NULL)
	{
		sjme_seterror(error, SJME_ERROR_INVALIDARG, 0);
		
		return;
	}
	
	/* Read current value. */
	rv = sjme_vmmread(vmem, SJME_VMMTYPE_INTEGER, ptr, off, error);
	
	/* If value is the same, set it. */
	if (rv == check)
		sjme_vmmwrite(vmem, SJME_VMMTYPE_INTEGER, ptr, off, set, error);
	
	/* Return the value. */
	return rv;
}

/** Atomically increments and integer and then gets its value. */
sjme_jint sjme_vmmatomicintaddandget(sjme_vmem* vmem,
	sjme_vmemptr ptr, sjme_jint off, sjme_jint add, sjme_error* error)
{
	sjme_jint rv;
	
	/* Invalid argument? */
	if (vmem == NULL)
	{
		sjme_seterror(error, SJME_ERROR_INVALIDARG, 0);
		
		return;
	}
	
	/* Read current value. */
	rv = sjme_vmmread(vmem, SJME_VMMTYPE_INTEGER, ptr, off, error);
	
	/* Add value. */
	rv += add;
	
	/* Store new value. */
	sjme_vmmwrite(vmem, SJME_VMMTYPE_INTEGER, ptr, off, rv, error);
	
	/* Return new value. */
	return rv;
}

Changes to runt/apis/cldc-compact/cc/squirreljme/jvm/Assembly.java.

36
37
38
39
40
41
42






























43
44
45
46
47
48
49
	 *
	 * @param __o The object to get the length of.
	 * @return The length of the array.
	 * @since 2019/05/24
	 */
	public static native int arrayLength(Object __o);
	






























	/**
	 * Trigger breakpoint within the virtual machine.
	 *
	 * @since 2019/04/21
	 */
	public static native void breakpoint();
	







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
	 *
	 * @param __o The object to get the length of.
	 * @return The length of the array.
	 * @since 2019/05/24
	 */
	public static native int arrayLength(Object __o);
	
	/**
	 * Atomic comparison and set.
	 *
	 * @param __comp The value to compare and if matches, {@code __set} is
	 * written.
	 * @param __set The value to set if matched.
	 * @param __addr The address to write to.
	 * @return The value that was read before the set.
	 * @since 2019/07/01
	 */
	public static native int atomicCompareGetAndSet(int __comp, int __set,
		int __addr);
	
	/**
	 * Atomically decrements a value and returns the result.
	 *
	 * @param __addr The address to decrement.
	 * @return The get value.
	 * @since 2019/07/01
	 */
	public static native int atomicDecrementAndGet(int __addr);
	
	/**
	 * Atomically increments a value.
	 *
	 * @param __addr The address to increment.
	 * @since 2019/07/01
	 */
	public static native void atomicIncrement(int __addr);
	
	/**
	 * Trigger breakpoint within the virtual machine.
	 *
	 * @since 2019/04/21
	 */
	public static native void breakpoint();
	

Changes to runt/klib/supervisor/cc/squirreljme/jvm/Assembly.java.

36
37
38
39
40
41
42






























43
44
45
46
47
48
49
	 *
	 * @param __o The object to get the length of.
	 * @return The length of the array.
	 * @since 2019/05/24
	 */
	public static native int arrayLength(Object __o);
	






























	/**
	 * Trigger breakpoint within the virtual machine.
	 *
	 * @since 2019/04/21
	 */
	public static native void breakpoint();
	







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
	 *
	 * @param __o The object to get the length of.
	 * @return The length of the array.
	 * @since 2019/05/24
	 */
	public static native int arrayLength(Object __o);
	
	/**
	 * Atomic comparison and set.
	 *
	 * @param __comp The value to compare and if matches, {@code __set} is
	 * written.
	 * @param __set The value to set if matched.
	 * @param __addr The address to write to.
	 * @return The value that was read before the set.
	 * @since 2019/07/01
	 */
	public static native int atomicCompareGetAndSet(int __comp, int __set,
		int __addr);
	
	/**
	 * Atomically decrements a value and returns the result.
	 *
	 * @param __addr The address to decrement.
	 * @return The get value.
	 * @since 2019/07/01
	 */
	public static native int atomicDecrementAndGet(int __addr);
	
	/**
	 * Atomically increments a value.
	 *
	 * @param __addr The address to increment.
	 * @since 2019/07/01
	 */
	public static native void atomicIncrement(int __addr);
	
	/**
	 * Trigger breakpoint within the virtual machine.
	 *
	 * @since 2019/04/21
	 */
	public static native void breakpoint();
	

Changes to runt/libs/summercoat-vm/cc/squirreljme/vm/summercoat/NativeCPU.java.

451
452
453
454
455
456
457



























458
459
460
461
462
463
464
					this.__debugExit(nowframe);
					break;
					
					// Debug point in method.
				case NativeInstructionType.DEBUG_POINT:
					this.__debugPoint(nowframe, args[0], args[1], args[2]);
					break;



























				
					// Atomic decrement and get
				case NativeInstructionType.ATOMIC_INT_DECREMENT_AND_GET:
					synchronized (memory)
					{
						// The address to load from/store to
						int addr = lr[args[1]],







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
					this.__debugExit(nowframe);
					break;
					
					// Debug point in method.
				case NativeInstructionType.DEBUG_POINT:
					this.__debugPoint(nowframe, args[0], args[1], args[2]);
					break;
					
					// Atomic compare, get, and set
				case NativeInstructionType.ATOMIC_COMPARE_GET_AND_SET:
					synchronized (memory)
					{
						// Read parameters
						int check = lr[args[0]],
							set = lr[args[2]],
							addr = lr[args[3]],
							off = args[4];
						
						// Read value here
						int read = memory.memReadInt(addr + off);
						
						// Is the value the same?
						if (read == check)
							memory.memWriteInt(addr + off, set);
						
						// Set the read value before check
						lr[args[1]] = read;
						
						// Debug
						if (ENABLE_DEBUG)
							todo.DEBUG.note("%08x(%d) = %d ? %d = %d",
								addr, off, read, check, set);
					}
					break;
				
					// Atomic decrement and get
				case NativeInstructionType.ATOMIC_INT_DECREMENT_AND_GET:
					synchronized (memory)
					{
						// The address to load from/store to
						int addr = lr[args[1]],

Changes to runt/libs/tool-classfile/dev/shadowtail/classfile/nncc/NativeInstruction.java.

309
310
311
312
313
314
315



316
317
318
319
320
321
322
...
424
425
426
427
428
429
430









431
432
433
434
435
436
437
			case NativeInstructionType.MATH_REG_INT:
			case NativeInstructionType.MATH_CONST_INT:
			case NativeInstructionType.MEMORY_OFF_REG:
			case NativeInstructionType.MEMORY_OFF_REG_JAVA:
			case NativeInstructionType.MEMORY_OFF_ICONST:
			case NativeInstructionType.MEMORY_OFF_ICONST_JAVA:
				return 3;



				
				// {@squirreljme.error JC10 Unknown instruction argument
				// count.}
			default:
				throw new InvalidInstructionException("JC10 " + __op);
		}
	}
................................................................................
					ArgumentFormat.VJUMP);
				
				// [reg w/ memaddr, reglist]
			case NativeInstructionType.INVOKE:
				return ArgumentFormat.of(
					ArgumentFormat.VUREG,
					ArgumentFormat.REGLIST);









		}
		
		// {@squirreljme.error JC11 Invalid operation. (The operation)}
		throw new InvalidInstructionException("JC11 " +
			NativeInstruction.mnemonic(__op));
	}
	







>
>
>







 







>
>
>
>
>
>
>
>
>







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
...
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
			case NativeInstructionType.MATH_REG_INT:
			case NativeInstructionType.MATH_CONST_INT:
			case NativeInstructionType.MEMORY_OFF_REG:
			case NativeInstructionType.MEMORY_OFF_REG_JAVA:
			case NativeInstructionType.MEMORY_OFF_ICONST:
			case NativeInstructionType.MEMORY_OFF_ICONST_JAVA:
				return 3;
			
			case NativeInstructionType.ATOMIC_COMPARE_GET_AND_SET:
				return 5;
				
				// {@squirreljme.error JC10 Unknown instruction argument
				// count.}
			default:
				throw new InvalidInstructionException("JC10 " + __op);
		}
	}
................................................................................
					ArgumentFormat.VJUMP);
				
				// [reg w/ memaddr, reglist]
			case NativeInstructionType.INVOKE:
				return ArgumentFormat.of(
					ArgumentFormat.VUREG,
					ArgumentFormat.REGLIST);
			
				// [r16 (check), r16 (get), r16 (set), r16 (addr), u16 (off)]
			case NativeInstructionType.ATOMIC_COMPARE_GET_AND_SET:
				return ArgumentFormat.of(
					ArgumentFormat.VUREG,
					ArgumentFormat.VUREG,
					ArgumentFormat.VUREG,
					ArgumentFormat.VUREG,
					ArgumentFormat.VUINT);
		}
		
		// {@squirreljme.error JC11 Invalid operation. (The operation)}
		throw new InvalidInstructionException("JC11 " +
			NativeInstruction.mnemonic(__op));
	}
	

Changes to runt/libs/tool-classfile/dev/shadowtail/classfile/nncc/NativeInstructionType.java.

121
122
123
124
125
126
127




128
129
130
131
132
133
134
	/** Atomically increments a memory address. */
	public static final short ATOMIC_INT_INCREMENT =
		0xFA;
	
	/** System call. */
	public static final short SYSTEM_CALL =
		0xFB;




	
	/**
	 * Load from pool, note that at code gen time this is aliased.
	 * {@code iiiixxxx}.
	 */
	public static final short LOAD_POOL =
		0xFD;







>
>
>
>







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
	/** Atomically increments a memory address. */
	public static final short ATOMIC_INT_INCREMENT =
		0xFA;
	
	/** System call. */
	public static final short SYSTEM_CALL =
		0xFB;
	
	/** Atomic compare and set. */
	public static final short ATOMIC_COMPARE_GET_AND_SET =
		0xFC;
	
	/**
	 * Load from pool, note that at code gen time this is aliased.
	 * {@code iiiixxxx}.
	 */
	public static final short LOAD_POOL =
		0xFD;

Changes to runt/libs/tool-classfile/dev/shadowtail/classfile/nncc/NearNativeByteCodeHandler.java.

2096
2097
2098
2099
2100
2101
2102




























2103
2104
2105
2106
2107
2108
2109
		String asmfunc;
		switch ((asmfunc = __name.toString()))
		{
				// Read lenght of array
			case "arrayLength":
				this.doArrayLength(__in[0], __out);
				break;




























				
				// Breakpoint
			case "breakpoint":
				codebuilder.add(NativeInstructionType.BREAKPOINT);
				break;
				
				// Long/Double bits







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
		String asmfunc;
		switch ((asmfunc = __name.toString()))
		{
				// Read lenght of array
			case "arrayLength":
				this.doArrayLength(__in[0], __out);
				break;
				
				// Atomic compare, get and set
			case "atomicCompareGetAndSet":
				codebuilder.add(
					NativeInstructionType.ATOMIC_COMPARE_GET_AND_SET,
						__in[0].register,
						__out.register,
						__in[1].register,
						__in[2].register,
						0);
				break;
				
				// Atomic decrement and get
			case "atomicDecrementAndGet":
				codebuilder.add(
					NativeInstructionType.ATOMIC_INT_DECREMENT_AND_GET,
						__out.register,
						__in[0].register,
						0);
				break;
				
				// Atomic increment
			case "atomicIncrement":
				codebuilder.add(
					NativeInstructionType.ATOMIC_INT_INCREMENT,
						__in[0].register,
						0);
				break;
				
				// Breakpoint
			case "breakpoint":
				codebuilder.add(NativeInstructionType.BREAKPOINT);
				break;
				
				// Long/Double bits