private void ClearPage(int page, bool pageZero) { if (Key.HasObjectsToSerialize() || Value.HasObjectsToSerialize()) { long ptr = (long)pointers[page]; int numBytes = PageSize; long endptr = ptr + numBytes; if (pageZero) { ptr += Constants.kFirstValidAddress; } List <long> addr = new List <long>(); while (ptr < endptr) { if (!Layout.GetInfo(ptr)->Invalid) { if (Key.HasObjectsToSerialize()) { Key *key = Layout.GetKey(ptr); Key.Free(key); } if (Value.HasObjectsToSerialize()) { Value *value = Layout.GetValue(ptr); Value.Free(value); } } ptr += Layout.GetPhysicalSize(ptr); } } Array.Clear(values[page], 0, values[page].Length); }
public override void Debug_Dump(bool detailed) { Contract.Requires(m_start != null && m_current != null); Value *current = (Value *)m_start; Value *end = (Value *)m_current; Trace.WriteLine(" # ValuePage: count=" + m_count.ToString("N0") + ", used=" + this.MemoryUsage.ToString("N0") + ", capacity=" + m_capacity.ToString("N0") + ", start=0x" + new IntPtr(m_start).ToString("X8") + ", end=0x" + new IntPtr(m_current).ToString("X8")); if (detailed) { while (current < end) { Trace.WriteLine(" - [" + Entry.GetObjectType(current).ToString() + "] 0x" + new IntPtr(current).ToString("X8") + " : " + current->Header.ToString("X8") + ", seq=" + current->Sequence + ", size=" + current->Size + " : " + Value.GetData(current).ToSlice().ToAsciiOrHexaString()); if (current->Previous != null) { Trace.WriteLine(" -> Previous: [" + Entry.GetObjectType(current->Previous) + "] 0x" + new IntPtr(current->Previous).ToString("X8")); } if (current->Parent != null) { Trace.WriteLine(" <- Parent: [" + Entry.GetObjectType(current->Parent) + "] 0x" + new IntPtr(current->Parent).ToString("X8")); } current = Value.WalkNext(current); } } }
//直接通过指针操作栈,调用add方法 //虚拟机内部方法间调用是通过这种方式 unsafe static void UnsafeCall() { IntPtr nativePointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(sizeof(Value) * VirtualMachine.MAX_EVALUATION_STACK_SIZE); Value *evaluationStackPointer = (Value *)nativePointer.ToPointer(); object[] managedStack = new object[VirtualMachine.MAX_EVALUATION_STACK_SIZE]; int LOOPS = 10000000; var virtualMachine = SimpleVirtualMachineBuilder.CreateVirtualMachine(LOOPS); var sw = Stopwatch.StartNew(); for (int i = 0; i < LOOPS; i++) { evaluationStackPointer->Value1 = 10; evaluationStackPointer->Type = IFix.Core.ValueType.Integer; (evaluationStackPointer + 1)->Value1 = 20; (evaluationStackPointer + 1)->Type = IFix.Core.ValueType.Integer; virtualMachine.Execute(0, evaluationStackPointer, managedStack, evaluationStackPointer, 2); } Console.WriteLine("UnsafeCall " + " : " + (LOOPS / (int)sw.Elapsed.TotalMilliseconds * 1000) + "\r\n"); System.Runtime.InteropServices.Marshal.FreeHGlobal(nativePointer); }
public static void PushObject(Value *evaluationStackBase, Value *evaluationStackPointer, object[] managedStack, object obj, Type type) { if (obj != null) { if (type.IsPrimitive) { UnboxPrimitive(evaluationStackPointer, obj, type); return; } else if (type.IsEnum) { var underlyingType = Enum.GetUnderlyingType(type); if (underlyingType == typeof(long) || underlyingType == typeof(ulong)) { evaluationStackPointer->Type = ValueType.Long; *(long *)(&evaluationStackPointer->Value1) = underlyingType == typeof(long) ? Convert.ToInt64(obj) : (long)Convert.ToUInt64(obj); } else { evaluationStackPointer->Type = ValueType.Integer; evaluationStackPointer->Value1 = Convert.ToInt32(obj); } return; } } int pos = (int)(evaluationStackPointer - evaluationStackBase); evaluationStackPointer->Value1 = pos; managedStack[pos] = obj; evaluationStackPointer->Type = (obj != null && type.IsValueType) ? ValueType.ValueType : ValueType.Object; }
/* * public unsafe JSCallArgs (Value* argv, UInt32 argc) { * this.argv = argv; * this.argc = argc; * } */ public unsafe JSCallArgs(JSCallArgumentsPtr argv, UInt32 argc) { Value *ptr = argv; // Native spidermonkey offsets the pointer so we have to do it too. ptr += 2; this.argv = ptr; this.argc = argc; }
public static USlice GetData(Value *value) { if (value == null) { return(default(USlice)); } Contract.Assert((value->Header & Entry.FLAGS_DISPOSED) == 0, "Attempt to read a value that was disposed"); return(new USlice(&(value->Data), value->Size)); }
public FileDataSet(string path, ulong offset, ulong count) { file = MemoryMappedFile.CreateFromFile(path, FileMode.Open); view = file.CreateViewAccessor(); byte *ptr = null; view.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr); values = (Value *)(ptr + offset); this.count = count; }
unsafe internal void Ldfld(int fieldIndex, Value *evaluationStackBase, Value *evaluationStackPointer, object[] managedStack) { //VirtualMachine._Info("AnonymousStorey Ldfld fieldIndex:" + fieldIndex + "," // + unmanagedFields[fieldIndex].Type + "," + unmanagedFields[fieldIndex].Value1); *evaluationStackPointer = unmanagedFields[fieldIndex]; if (unmanagedFields[fieldIndex].Type >= ValueType.Object) { evaluationStackPointer->Value1 = (int)(evaluationStackPointer - evaluationStackBase); managedStack[evaluationStackPointer->Value1] = managedFields[fieldIndex]; } }
unsafe internal void Stfld(int fieldIndex, Value *evaluationStackBase, Value *evaluationStackPointer, object[] managedStack) { //VirtualMachine._Info("AnonymousStorey Stfld fieldIndex:" + fieldIndex + "," // + evaluationStackPointer->Type + "," + evaluationStackPointer->Value1); unmanagedFields[fieldIndex] = *evaluationStackPointer; if (evaluationStackPointer->Type >= ValueType.Object) { unmanagedFields[fieldIndex].Value1 = fieldIndex; managedFields[fieldIndex] = managedStack[evaluationStackPointer->Value1]; } }
public static bool StillAlive(Value *value, ulong sequence) { if (value == null) { return(false); } if ((value->Header & Value.FLAGS_MUTATED) != 0) { return(value->Sequence >= sequence); } return(true); }
public Value *Allocate(uint dataSize, ulong sequence, Value *previous, void *parent) { int bucket = GetBucket(dataSize + Value.SizeOf); var page = m_currents[bucket]; var entry = page != null?page.TryAllocate(dataSize, sequence, previous, parent) : null; if (entry == null) { entry = AllocateSlow(bucket, dataSize, sequence, previous, parent); } return(entry); }
/// <summary>Copy an existing value to this page, and return the pointer to the copy</summary> /// <param name="value">Value that must be copied to this page</param> /// <returns>Pointer to the copy in this page</returns> public Value *TryAppend(Value *value) { Contract.Requires(value != null && Entry.GetObjectType(value) == EntryType.Value); uint rawSize = Value.SizeOf + value->Size; Value *entry = (Value *)TryAllocate(rawSize); if (entry == null) { return(null); // the page is full } UnmanagedHelpers.CopyUnsafe((byte *)entry, (byte *)value, rawSize); return(entry); }
private Value *AllocateSlow(int bucket, uint dataSize, ulong sequence, Value *previous, void *parent) { var page = CreateNewPage(bucket); Contract.Assert(page != null); m_currents[bucket] = page; m_buckets[bucket].Pages.Add(page); var entry = page.TryAllocate(dataSize, sequence, previous, parent); if (entry == null) { throw new OutOfMemoryException(String.Format("Failed to allocate memory from the the value heap ({0})", m_buckets[bucket].PageSize)); } return(entry); }
public Value *TryAllocate(uint dataSize, ulong sequence, Value *previous, void *parent) { Value *entry = (Value *)TryAllocate(Value.SizeOf + dataSize); if (entry == null) { return(null); // the page is full } entry->Header = ((ushort)EntryType.Value) << Entry.TYPE_SHIFT; entry->Size = dataSize; entry->Sequence = sequence; entry->Previous = previous; entry->Parent = parent; return(entry); }
public Status Upsert(Key *key, Value *desiredValue, Context *userContext, long monotonicSerialNum) { var context = default(PendingContext); var internalStatus = InternalUpsert(key, desiredValue, userContext, ref context); var status = default(Status); if (internalStatus == OperationStatus.SUCCESS || internalStatus == OperationStatus.NOTFOUND) { status = (Status)internalStatus; } else { status = HandleOperationStatus(threadCtx, context, internalStatus); } threadCtx.serialNum = monotonicSerialNum; return(status); }
unsafe static void MarshalCallback(IntPtr raw_closure, Value *return_val, uint n_param_vals, Value *param_values, IntPtr invocation_hint, IntPtr marshal_data) { SignalClosure closure = null; try { closure = closures [raw_closure] as SignalClosure; GLib.Object __obj = param_values [0].Val as GLib.Object; if (__obj == null) { return; } if (closure.signal.args_type == typeof(EventArgs)) { closure.Invoke(new ClosureInvokedArgs(__obj, EventArgs.Empty)); return; } SignalArgs args = FastActivator.CreateSignalArgs(closure.signal.args_type); args.Args = new object [n_param_vals - 1]; for (int i = 1; i < n_param_vals; i++) { args.Args [i - 1] = param_values [i].Val; } ClosureInvokedArgs ci_args = new ClosureInvokedArgs(__obj, args); closure.Invoke(ci_args); for (int i = 1; i < n_param_vals; i++) { param_values [i].Update(args.Args [i - 1]); } if (return_val == null || args.RetVal == null) { return; } return_val->Val = args.RetVal; } catch (Exception e) { if (closure != null) { Console.WriteLine("Marshaling {0} signal", closure.signal.name); } ExceptionManager.RaiseUnhandledException(e, false); } }
public unsafe void Add(ulong sequence, USlice userKey, USlice userValue) { // allocate the key var tmp = MemoryDatabaseHandler.PackUserKey(m_scratch, userKey); Key *key = m_keys.Append(tmp); Contract.Assert(key != null, "key == null"); // allocate the value uint size = userValue.Count; Value *value = m_values.Allocate(size, sequence, null, key); Contract.Assert(value != null, "value == null"); UnmanagedHelpers.CopyUnsafe(&(value->Data), userValue); key->Values = value; m_list.Add(new IntPtr(key)); }
/// <summary> /// Clear page /// </summary> /// <param name="ptr">From pointer</param> /// <param name="endptr">Until pointer</param> public void ClearPage(long ptr, long endptr) { while (ptr < endptr) { if (!Layout.GetInfo(ptr)->Invalid) { if (Key.HasObjectsToSerialize()) { Key *key = Layout.GetKey(ptr); Key.Free(key); } if (Value.HasObjectsToSerialize()) { Value *value = Layout.GetValue(ptr); Value.Free(value); } } ptr += Layout.GetPhysicalSize(ptr); } }
/// <summary> /// Serialize part of page to stream /// </summary> /// <param name="ptr">From pointer</param> /// <param name="untilptr">Until pointer</param> /// <param name="stream">Stream</param> /// <param name="objectBlockSize">Size of blocks to serialize in chunks of</param> /// <param name="addr">List of addresses that need to be updated with offsets</param> public void Serialize(ref long ptr, long untilptr, Stream stream, int objectBlockSize, out List <long> addr) { addr = new List <long>(); while (ptr < untilptr) { if (!Layout.GetInfo(ptr)->Invalid) { long pos = stream.Position; if (Key.HasObjectsToSerialize()) { Key *key = Layout.GetKey(ptr); Key.Serialize(key, stream); ((AddressInfo *)key)->Address = pos; ((AddressInfo *)key)->Size = (int)(stream.Position - pos); addr.Add((long)key); } if (Value.HasObjectsToSerialize()) { pos = stream.Position; Value *value = Layout.GetValue(ptr); Value.Serialize(value, stream); ((AddressInfo *)value)->Address = pos; ((AddressInfo *)value)->Size = (int)(stream.Position - pos); addr.Add((long)value); } } ptr += Layout.GetPhysicalSize(ptr); if (stream.Position > objectBlockSize) { return; } } }
public Status Upsert(Key *key, Value *desiredValue, Context *userContext, long monotonicSerialNum) { /* * Console.WriteLine(hlog.GetPhysicalAddress(0)); * if (((RecordInfo*)hlog.GetPhysicalAddress(0))->Invalid != true) * { * Debugger.Break(); * }*/ var context = default(PendingContext); var internalStatus = InternalUpsert(key, desiredValue, userContext, ref context); var status = default(Status); if (internalStatus == OperationStatus.SUCCESS || internalStatus == OperationStatus.NOTFOUND) { status = (Status)internalStatus; } else { status = HandleOperationStatus(threadCtx, context, internalStatus); } threadCtx.serialNum = monotonicSerialNum; return(status); }
public static unsafe Value *GetList(ref int arrayLength) { int count = 2; arrayLength = count; Value *result = null; Value[] data = new Value[count]; for (int i = 0; i < count; i++) { Value value = new Value() { FieldInt = i, FieldDouble = i }; data[i] = value; } fixed(Value *current = &data[0], last = &data[count - 1]) { result = current; return(result); } }
public static void UpdateReference(Value *evaluationStackBase, Value *evaluationStackPointer, object[] managedStack, object obj, VirtualMachine virtualMachine, Type type) //反射专用 { switch (evaluationStackPointer->Type) { case ValueType.StackReference: var des = *(Value **)&evaluationStackPointer->Value1; //VirtualMachine._Info("UpdateReference des->Type:" + des->Type + ", des->Value1:" // + des->Value1 + ", des:" + new IntPtr(des) + ", offset:" + (des - evaluationStackBase) ); PushObject(evaluationStackBase, des, managedStack, obj, type); break; case ValueType.ArrayReference: var arr = managedStack[evaluationStackPointer->Value1] as Array; arr.SetValue(obj, evaluationStackPointer->Value2); break; case ValueType.FieldReference: case ValueType.ChainFieldReference: { if (evaluationStackPointer->Type == ValueType.ChainFieldReference) { var fieldAddr = managedStack[evaluationStackPointer - evaluationStackBase] as FieldAddr; var fieldIdList = fieldAddr.FieldIdList; //for(int i = 0; i < fieldIdList.Length; i++) //{ // VirtualMachine._Info("fid " + i + ": " + fieldIdList[i] + ", " // + virtualMachine.fieldInfos[fieldIdList[i]]); //} mSet(evaluationStackPointer->Value2 != -1, fieldAddr.Object, obj, fieldIdList.Length - 1, fieldIdList, virtualMachine.fieldInfos, virtualMachine.newFieldInfos); } else { if (evaluationStackPointer->Value2 >= 0) { var fieldInfo = virtualMachine.fieldInfos[evaluationStackPointer->Value2]; if (fieldInfo == null) { virtualMachine.newFieldInfos[evaluationStackPointer->Value2].SetValue(managedStack[evaluationStackPointer->Value1], obj);; } else { //VirtualMachine._Info("update field: " + fieldInfo); //VirtualMachine._Info("update field of: " + fieldInfo.DeclaringType); //VirtualMachine._Info("update ref obj: " // + managedStack[evaluationStackPointer->Value1]); //VirtualMachine._Info("update ref obj idx: " + evaluationStackPointer->Value1); fieldInfo.SetValue(managedStack[evaluationStackPointer->Value1], obj); } } else { var anonymousStorey = managedStack[evaluationStackPointer->Value1] as AnonymousStorey; anonymousStorey.Set(-(evaluationStackPointer->Value2 + 1), obj, type, virtualMachine); } } break; } case ValueType.StaticFieldReference: //更新完毕,直接return { var fieldIndex = evaluationStackPointer->Value1; if (fieldIndex >= 0) { var fieldInfo = virtualMachine.fieldInfos[evaluationStackPointer->Value1]; if (fieldInfo == null) { virtualMachine.newFieldInfos[evaluationStackPointer->Value1].SetValue(null, obj);; } else { fieldInfo.SetValue(null, obj); } } else { fieldIndex = -(fieldIndex + 1); virtualMachine.staticFields[fieldIndex] = obj; } break; } } }
// #lizard forgives internal static unsafe object ToObject(Value *evaluationStackBase, Value *evaluationStackPointer, object[] managedStack, Type type, VirtualMachine virtualMachine, bool valueTypeClone = true) { //未初始化的local引用可能作为out参数反射调用 //TODO: 验证值类型out参数,对应参数位置是否可以是null? switch (evaluationStackPointer->Type) { case ValueType.Integer: { int i = evaluationStackPointer->Value1; if (type == typeof(int)) { return(i); } else if (type == typeof(bool)) { return(i == 1); } else if (type == typeof(sbyte)) { return((sbyte)i); } else if (type == typeof(byte)) { return((byte)i); } else if (type == typeof(char)) { return((char)i); } else if (type == typeof(short)) { return((short)i); } else if (type == typeof(ushort)) { return((ushort)i); } else if (type == typeof(uint)) { return((uint)i); } else if (type.IsEnum) { return(Enum.ToObject(type, i)); } else { return(null); } } case ValueType.Long: { long l = *(long *)&evaluationStackPointer->Value1; if (type == typeof(long)) { return(l); } else if (type == typeof(ulong)) { return((ulong)l); } else if (type == typeof(IntPtr)) { return(new IntPtr(l)); } else if (type == typeof(UIntPtr)) { return(new UIntPtr((ulong)l)); } else if (type.IsEnum) { return(Enum.ToObject(type, l)); } else { return(null); } } case ValueType.Float: { if (type == typeof(float)) { return(*(float *)&evaluationStackPointer->Value1); } else { return(null); } } case ValueType.Double: { if (type == typeof(double)) { return(*(double *)&evaluationStackPointer->Value1); } else { return(null); } } case ValueType.Object: return(managedStack[evaluationStackPointer->Value1]); case ValueType.ValueType: if (valueTypeClone && managedStack[evaluationStackPointer->Value1] != null) { return(virtualMachine.objectClone.Clone(managedStack[evaluationStackPointer->Value1])); } else { return(managedStack[evaluationStackPointer->Value1]); } case ValueType.StackReference: { return(ToObject(evaluationStackBase, (*(Value **)&evaluationStackPointer->Value1), managedStack, type, virtualMachine, valueTypeClone)); } case ValueType.FieldReference: case ValueType.ChainFieldReference: { //VirtualMachine._Info("ToObject FieldReference:" + evaluationStackPointer->Value2 // + "," + evaluationStackPointer->Value1); if (evaluationStackPointer->Type == ValueType.ChainFieldReference) { var fieldAddr = managedStack[evaluationStackPointer - evaluationStackBase] as FieldAddr; var fieldIdList = fieldAddr.FieldIdList; return(mGet(evaluationStackPointer->Value2 != -1, fieldAddr.Object, fieldIdList.Length - 1, fieldIdList, virtualMachine.fieldInfos, virtualMachine.newFieldInfos)); } else { if (evaluationStackPointer->Value2 >= 0) { var fieldInfo = virtualMachine.fieldInfos[evaluationStackPointer->Value2]; var obj = managedStack[evaluationStackPointer->Value1]; if (fieldInfo == null) { virtualMachine.newFieldInfos[evaluationStackPointer->Value2].CheckInit(virtualMachine, obj); return(virtualMachine.newFieldInfos[evaluationStackPointer->Value2].GetValue(obj)); } return(fieldInfo.GetValue(obj)); } else { var obj = managedStack[evaluationStackPointer->Value1] as AnonymousStorey; return(obj.Get(-(evaluationStackPointer->Value2 + 1), type, virtualMachine, valueTypeClone)); } } } case ValueType.ArrayReference: var arr = managedStack[evaluationStackPointer->Value1] as Array; return(arr.GetValue(evaluationStackPointer->Value2)); case ValueType.StaticFieldReference: { var fieldIndex = evaluationStackPointer->Value1; if (fieldIndex >= 0) { var fieldInfo = virtualMachine.fieldInfos[fieldIndex]; if (fieldInfo == null) { virtualMachine.newFieldInfos[fieldIndex].CheckInit(virtualMachine, null); return(virtualMachine.newFieldInfos[fieldIndex].GetValue(null)); } return(fieldInfo.GetValue(null)); } else { fieldIndex = -(fieldIndex + 1); return(virtualMachine.staticFields[fieldIndex]); } } default: throw new NotImplementedException("get obj of " + evaluationStackPointer->Type); } }
private void WriteAsync <TContext>(IntPtr alignedSourceAddress, ulong alignedDestinationAddress, uint numBytesToWrite, IOCompletionCallback callback, PageAsyncFlushResult <TContext> asyncResult, IDevice device, ISegmentedDevice objlogDevice) { if (!Key.HasObjectsToSerialize() && !Value.HasObjectsToSerialize()) { device.WriteAsync(alignedSourceAddress, alignedDestinationAddress, numBytesToWrite, callback, asyncResult); return; } // need to write both page and object cache asyncResult.count++; MemoryStream ms = new MemoryStream(); var buffer = ioBufferPool.Get(PageSize); Buffer.MemoryCopy((void *)alignedSourceAddress, buffer.aligned_pointer, numBytesToWrite, numBytesToWrite); long ptr = (long)buffer.aligned_pointer; List <long> addr = new List <long>(); asyncResult.freeBuffer1 = buffer; // Correct for page 0 of HLOG if (alignedDestinationAddress >> LogPageSizeBits == 0) { ptr += Constants.kFirstValidAddress; } while (ptr < (long)buffer.aligned_pointer + numBytesToWrite) { if (!Layout.GetInfo(ptr)->Invalid) { long pos = ms.Position; Key *key = Layout.GetKey(ptr); Key.Serialize(key, ms); ((AddressInfo *)key)->IsDiskAddress = true; ((AddressInfo *)key)->Address = pos; ((AddressInfo *)key)->Size = (int)(ms.Position - pos); addr.Add((long)key); pos = ms.Position; Value *value = Layout.GetValue(ptr); Value.Serialize(value, ms); ((AddressInfo *)value)->IsDiskAddress = true; ((AddressInfo *)value)->Address = pos; ((AddressInfo *)value)->Size = (int)(ms.Position - pos); addr.Add((long)value); } ptr += Layout.GetPhysicalSize(ptr); } var s = ms.ToArray(); var objBuffer = ioBufferPool.Get(s.Length); asyncResult.freeBuffer2 = objBuffer; var alignedLength = (s.Length + (sectorSize - 1)) & ~(sectorSize - 1); var objAddr = Interlocked.Add(ref segmentOffsets[(alignedDestinationAddress >> LogSegmentSizeBits) % SegmentBufferSize], alignedLength) - alignedLength; fixed(void *src = s) Buffer.MemoryCopy(src, objBuffer.aligned_pointer, s.Length, s.Length); foreach (var address in addr) { *((long *)address) += objAddr; } objlogDevice.WriteAsync( (IntPtr)objBuffer.aligned_pointer, (int)(alignedDestinationAddress >> LogSegmentSizeBits), (ulong)objAddr, (uint)alignedLength, callback, asyncResult); device.WriteAsync((IntPtr)buffer.aligned_pointer, alignedDestinationAddress, numBytesToWrite, callback, asyncResult); }
private void AsyncReadPageCallback <TContext>(uint errorCode, uint numBytes, NativeOverlapped *overlap) { if (errorCode != 0) { Trace.TraceError("OverlappedStream GetQueuedCompletionStatus error: {0}", errorCode); } PageAsyncReadResult <TContext> result = (PageAsyncReadResult <TContext>)Overlapped.Unpack(overlap).AsyncResult; if (Interlocked.Decrement(ref result.count) == 1) { // We will be issuing another I/O, so free this overlap Overlapped.Free(overlap); long ptr = (long)pointers[result.page % BufferSize]; // Correct for page 0 of HLOG if (result.page == 0) { ptr += Constants.kFirstValidAddress; } long minObjAddress = long.MaxValue; long maxObjAddress = long.MinValue; while (ptr < (long)pointers[result.page % BufferSize] + PageSize) { if (!Layout.GetInfo(ptr)->Invalid) { if (Key.HasObjectsToSerialize()) { Key *key = Layout.GetKey(ptr); var addr = ((AddressInfo *)key)->Address; if (addr < minObjAddress) { minObjAddress = addr; } addr += ((AddressInfo *)key)->Size; if (addr > maxObjAddress) { maxObjAddress = addr; } } if (Value.HasObjectsToSerialize()) { Value *value = Layout.GetValue(ptr); var addr = ((AddressInfo *)value)->Address; if (addr < minObjAddress) { minObjAddress = addr; } addr += ((AddressInfo *)value)->Size; if (addr > maxObjAddress) { maxObjAddress = addr; } } } ptr += Layout.GetPhysicalSize(ptr); } // Object log fragment should be aligned by construction Debug.Assert(minObjAddress % sectorSize == 0); var to_read = (int)(maxObjAddress - minObjAddress); var objBuffer = ioBufferPool.Get(to_read); result.freeBuffer1 = objBuffer; var alignedLength = (to_read + (sectorSize - 1)) & ~(sectorSize - 1); // Request objects from objlog result.objlogDevice.ReadAsync( (int)(result.page >> (LogSegmentSizeBits - LogPageSizeBits)), (ulong)minObjAddress, (IntPtr)objBuffer.aligned_pointer, (uint)alignedLength, AsyncReadPageCallback <TContext>, result); } else { // Load objects from buffer into memory long ptr = (long)pointers[result.page % BufferSize]; // Correct for page 0 of HLOG if (result.page == 0) { ptr += Constants.kFirstValidAddress; } MemoryStream ms = new MemoryStream(result.freeBuffer1.buffer); ms.Seek(result.freeBuffer1.offset + result.freeBuffer1.valid_offset, SeekOrigin.Begin); while (ptr < (long)pointers[result.page % BufferSize] + PageSize) { if (!Layout.GetInfo(ptr)->Invalid) { if (Key.HasObjectsToSerialize()) { Key.Deserialize(Layout.GetKey(ptr), ms); } if (Value.HasObjectsToSerialize()) { Value.Deserialize(Layout.GetValue(ptr), ms); } } ptr += Layout.GetPhysicalSize(ptr); } ms.Dispose(); result.Free(); // Call the "real" page read callback result.callback(errorCode, numBytes, overlap); } }
/// <summary>Return the address of the following value in the heap</summary> internal static Value *WalkNext(Value *self) { Contract.Requires(self != null && Entry.GetObjectType(self) == EntryType.Value); return((Value *)Entry.Align((byte *)self + Value.SizeOf + self->Size)); }
public static bool IsDisposed(Value *value) { return((value->Header & Entry.FLAGS_DISPOSED) != 0); }
public void PushObjectAsResult(object obj, Type type) //反射专用 { EvaluationStackOperation.PushObject(evaluationStackBase, argumentBase, managedStack, obj, type); currentTop = argumentBase + 1; }
internal static void UnboxPrimitive(Value *evaluationStackPointer, object obj, Type type) { if (obj.GetType().IsEnum) { obj = Convert.ChangeType(obj, type); } if (obj is int) { evaluationStackPointer->Type = ValueType.Integer; evaluationStackPointer->Value1 = (int)obj; } else if (obj is float) { evaluationStackPointer->Type = ValueType.Float; *(float *)(&evaluationStackPointer->Value1) = (float)obj; } else if (obj is bool) { evaluationStackPointer->Type = ValueType.Integer; evaluationStackPointer->Value1 = (bool)(obj) ? 1 : 0; } else if (obj is double) { evaluationStackPointer->Type = ValueType.Double; *(double *)(&evaluationStackPointer->Value1) = (double)obj; } else if (obj is long) { evaluationStackPointer->Type = ValueType.Long; *(long *)(&evaluationStackPointer->Value1) = (long)obj; } else if (obj is byte) { evaluationStackPointer->Type = ValueType.Integer; evaluationStackPointer->Value1 = (byte)obj; } else if (obj is uint) { evaluationStackPointer->Type = ValueType.Integer; evaluationStackPointer->Value1 = (int)(uint)obj; } else if (obj is ushort) { evaluationStackPointer->Type = ValueType.Integer; evaluationStackPointer->Value1 = (int)(ushort)obj; } else if (obj is short) { evaluationStackPointer->Type = ValueType.Integer; evaluationStackPointer->Value1 = (short)obj; } else if (obj is char) { evaluationStackPointer->Type = ValueType.Integer; evaluationStackPointer->Value1 = (int)(char)obj; } else if (obj is ulong) { evaluationStackPointer->Type = ValueType.Long; *(ulong *)(&evaluationStackPointer->Value1) = (ulong)obj; } else if (obj is sbyte) { evaluationStackPointer->Type = ValueType.Integer; evaluationStackPointer->Value1 = (sbyte)obj; } else if (obj is IntPtr) { evaluationStackPointer->Type = ValueType.Long; *(long *)(&evaluationStackPointer->Value1) = ((IntPtr)obj).ToInt64(); } else if (obj is UIntPtr) { evaluationStackPointer->Type = ValueType.Long; *(ulong *)(&evaluationStackPointer->Value1) = ((UIntPtr)obj).ToUInt64(); } else { throw new NotImplementedException("Unbox a " + obj.GetType() + " to " + type); } }
public JSCallArgumentsPtr(IntPtr ptr) { Values = (Value *)ptr.ToPointer(); }