Minor code cleanup. (#1264)
This commit is contained in:
@@ -29,14 +29,14 @@ static inline void copyImpl(KConstRef thiz, KInt fromIndex,
|
||||
const ArrayHeader* array = thiz->array();
|
||||
ArrayHeader* destinationArray = destination->array();
|
||||
if (count < 0 ||
|
||||
fromIndex < 0 || count > array->count_ - fromIndex ||
|
||||
toIndex < 0 || count > destinationArray->count_ - toIndex) {
|
||||
fromIndex < 0 || count > array->count_ - fromIndex ||
|
||||
toIndex < 0 || count > destinationArray->count_ - toIndex) {
|
||||
ThrowArrayIndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
memmove(PrimitiveArrayAddressOfElementAt<T>(destinationArray, toIndex),
|
||||
PrimitiveArrayAddressOfElementAt<T>(array, fromIndex),
|
||||
count * sizeof(T));
|
||||
count * sizeof(T));
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -117,9 +117,7 @@ _Unwind_Reason_Code unwindCallback(
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// TODO: this implementation is just a hack, e.g. the result is inexact;
|
||||
// however it is better to have an inexact stacktrace than not to have any.
|
||||
@@ -219,6 +217,4 @@ void SetKonanTerminateHandler() {
|
||||
|
||||
#endif // KONAN_OBJC_INTEROP
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
} // extern "C"
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef KOTLIN_KONAN_H
|
||||
#define KOTLIN_KONAN_H
|
||||
|
||||
// To embed Kotlin/Native into a C/C++ application this API could be used.
|
||||
// Compile Kotlin/Native application as usual, but supply -nomain kotlinc
|
||||
// switch, and provide bitcode with real entry point code as -nativelibrary
|
||||
// command line argument.
|
||||
extern "C" int Konan_main(int argc, const char** argv);
|
||||
|
||||
#endif // KOTLIN_KONAN_H
|
||||
@@ -582,7 +582,7 @@ void dumpWorker(const char* prefix, ContainerHeader* header, ContainerHeaderSet*
|
||||
traverseContainerReferredObjects(header, [prefix, seen](ObjHeader* ref) {
|
||||
auto child = ref->container();
|
||||
RuntimeAssert(!isArena(child), "A reference to local object is encountered");
|
||||
if (!isPermanent(child) && (seen->count(child) == 0)) {
|
||||
if (!child->permanent() && (seen->count(child) == 0)) {
|
||||
dumpWorker(prefix, child, seen);
|
||||
}
|
||||
});
|
||||
@@ -618,7 +618,7 @@ void MarkGray(ContainerHeader* container) {
|
||||
traverseContainerReferredObjects(container, [](ObjHeader* ref) {
|
||||
auto childContainer = ref->container();
|
||||
RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered");
|
||||
if (!isPermanent(childContainer)) {
|
||||
if (!childContainer->permanent()) {
|
||||
childContainer->decRefCount();
|
||||
MarkGray<useColor>(childContainer);
|
||||
}
|
||||
@@ -637,7 +637,7 @@ void ScanBlack(ContainerHeader* container) {
|
||||
traverseContainerReferredObjects(container, [](ObjHeader* ref) {
|
||||
auto childContainer = ref->container();
|
||||
RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered");
|
||||
if (!isPermanent(childContainer)) {
|
||||
if (!childContainer->permanent()) {
|
||||
childContainer->incRefCount();
|
||||
if (useColor) {
|
||||
if (childContainer->color() != CONTAINER_TAG_GC_BLACK)
|
||||
@@ -701,7 +701,7 @@ void Scan(ContainerHeader* container) {
|
||||
traverseContainerReferredObjects(container, [](ObjHeader* ref) {
|
||||
auto childContainer = ref->container();
|
||||
RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered");
|
||||
if (!isPermanent(childContainer)) {
|
||||
if (!childContainer->permanent()) {
|
||||
Scan(childContainer);
|
||||
}
|
||||
});
|
||||
@@ -715,7 +715,7 @@ void CollectWhite(MemoryState* state, ContainerHeader* container) {
|
||||
traverseContainerReferredObjects(container, [state](ObjHeader* ref) {
|
||||
auto childContainer = ref->container();
|
||||
RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered");
|
||||
if (!isPermanent(childContainer)) {
|
||||
if (!childContainer->permanent()) {
|
||||
CollectWhite(state, childContainer);
|
||||
}
|
||||
});
|
||||
@@ -799,7 +799,7 @@ ContainerHeader* AllocContainer(size_t size) {
|
||||
}
|
||||
|
||||
void FreeContainer(ContainerHeader* header) {
|
||||
RuntimeAssert(!isPermanent(header), "this kind of container shalln't be freed");
|
||||
RuntimeAssert(!header->permanent(), "this kind of container shalln't be freed");
|
||||
auto state = memoryState;
|
||||
|
||||
CONTAINER_FREE_EVENT(state, header)
|
||||
@@ -1080,7 +1080,7 @@ OBJ_GETTER(InitInstance,
|
||||
}
|
||||
|
||||
bool HasReservedObjectTail(ObjHeader* obj) {
|
||||
return kObjectReservedTailSize != 0 && !isPermanent(obj);
|
||||
return kObjectReservedTailSize != 0 && !obj->permanent();
|
||||
}
|
||||
|
||||
void* GetReservedObjectTail(ObjHeader* obj) {
|
||||
@@ -1300,7 +1300,7 @@ bool hasExternalRefs(ContainerHeader* container, ContainerHeaderSet* visited) {
|
||||
bool result = container->refCount() != 0;
|
||||
traverseContainerReferredObjects(container, [&result, visited](ObjHeader* ref) {
|
||||
auto child = ref->container();
|
||||
if (!isPermanent(child) && (visited->find(child) == visited->end())) {
|
||||
if (!child->permanent() && (visited->find(child) == visited->end())) {
|
||||
result |= hasExternalRefs(child, visited);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -24,15 +24,15 @@
|
||||
// Must fit in two bits.
|
||||
typedef enum {
|
||||
// Those bit masks are applied to refCount_ field.
|
||||
|
||||
// Container is normal thread local container.
|
||||
CONTAINER_TAG_NORMAL = 0,
|
||||
// Container shall be atomically refcounted, currently disabled.
|
||||
// CONTAINER_TAG_SHARED = 1,
|
||||
// Container is frozen, could only refer to other frozen objects.
|
||||
// Refcounter update is atomics.
|
||||
CONTAINER_TAG_FROZEN = 1,
|
||||
// Those container tags shall not be refcounted.
|
||||
// Permanent object, cannot refer to non-permanent objects, so no need to cleanup those.
|
||||
// Permanent container, cannot refer to non-permanent containers, so no need to cleanup those.
|
||||
CONTAINER_TAG_PERMANENT = 2,
|
||||
// Stack objects, no need to free, children cleanup still shall be there.
|
||||
// Stack container, no need to free, children cleanup still shall be there.
|
||||
CONTAINER_TAG_STACK = 3,
|
||||
// Shift to get actual counter.
|
||||
CONTAINER_TAG_SHIFT = 2,
|
||||
@@ -61,64 +61,78 @@ typedef uint32_t container_size_t;
|
||||
|
||||
// Header of all container objects. Contains reference counter.
|
||||
struct ContainerHeader {
|
||||
// Reference counter of container. Uses CONTAINER_TAG_SHIFT,lower bits of counter
|
||||
// Reference counter of container. Uses CONTAINER_TAG_SHIFT, lower bits of counter
|
||||
// for container type (for polymorphism in ::Release()).
|
||||
uint32_t refCount_;
|
||||
// Number of objects in the container.
|
||||
uint32_t objectCount_;
|
||||
|
||||
inline bool permanent() const {
|
||||
return (refCount_ & CONTAINER_TAG_MASK) == CONTAINER_TAG_PERMANENT;
|
||||
}
|
||||
|
||||
inline unsigned refCount() const {
|
||||
return refCount_ >> CONTAINER_TAG_SHIFT;
|
||||
}
|
||||
|
||||
inline void incRefCount() {
|
||||
refCount_ += CONTAINER_TAG_INCREMENT;
|
||||
}
|
||||
|
||||
inline int decRefCount() {
|
||||
refCount_ -= CONTAINER_TAG_INCREMENT;
|
||||
return refCount_ >> CONTAINER_TAG_SHIFT;
|
||||
}
|
||||
|
||||
inline unsigned tag() const {
|
||||
return refCount_ & CONTAINER_TAG_MASK;
|
||||
}
|
||||
|
||||
inline unsigned objectCount() const {
|
||||
return objectCount_ >> CONTAINER_TAG_GC_SHIFT;
|
||||
}
|
||||
|
||||
inline void incObjectCount() {
|
||||
objectCount_ += CONTAINER_TAG_GC_INCREMENT;
|
||||
}
|
||||
|
||||
inline void setObjectCount(int count) {
|
||||
objectCount_ = count << CONTAINER_TAG_GC_SHIFT;
|
||||
}
|
||||
|
||||
inline unsigned color() const {
|
||||
return objectCount_ & CONTAINER_TAG_GC_COLOR_MASK;
|
||||
}
|
||||
|
||||
inline void setColor(unsigned color) {
|
||||
objectCount_ = (objectCount_ & ~CONTAINER_TAG_GC_COLOR_MASK) | color;
|
||||
}
|
||||
|
||||
inline bool buffered() const {
|
||||
return (objectCount_ & CONTAINER_TAG_GC_BUFFERED) != 0;
|
||||
}
|
||||
|
||||
inline void setBuffered() {
|
||||
objectCount_ |= CONTAINER_TAG_GC_BUFFERED;
|
||||
}
|
||||
|
||||
inline void resetBuffered() {
|
||||
objectCount_ &= ~CONTAINER_TAG_GC_BUFFERED;
|
||||
}
|
||||
|
||||
inline bool marked() const {
|
||||
return (objectCount_ & CONTAINER_TAG_GC_MARKED) != 0;
|
||||
}
|
||||
|
||||
inline void mark() {
|
||||
objectCount_ |= CONTAINER_TAG_GC_MARKED;
|
||||
}
|
||||
|
||||
inline void unMark() {
|
||||
objectCount_ &= ~CONTAINER_TAG_GC_MARKED;
|
||||
}
|
||||
};
|
||||
|
||||
inline bool isPermanent(const ContainerHeader* header) {
|
||||
return (header->refCount_ & CONTAINER_TAG_MASK) == CONTAINER_TAG_PERMANENT;
|
||||
}
|
||||
|
||||
struct ArrayHeader;
|
||||
|
||||
// Header of every object.
|
||||
@@ -155,11 +169,11 @@ struct ObjHeader {
|
||||
// Unsafe cast to ArrayHeader. Use carefully!
|
||||
ArrayHeader* array() { return reinterpret_cast<ArrayHeader*>(this); }
|
||||
const ArrayHeader* array() const { return reinterpret_cast<const ArrayHeader*>(this); }
|
||||
};
|
||||
|
||||
inline bool isPermanent(const ObjHeader* obj) {
|
||||
return isPermanent(obj->container());
|
||||
}
|
||||
inline bool permanent() const {
|
||||
return container()->permanent();
|
||||
}
|
||||
};
|
||||
|
||||
// Header of value type array objects. Keep layout in sync with that of object header.
|
||||
struct ArrayHeader {
|
||||
@@ -280,13 +294,16 @@ class ArenaContainer {
|
||||
|
||||
private:
|
||||
void* place(container_size_t size);
|
||||
|
||||
bool allocContainer(container_size_t minSize);
|
||||
|
||||
void setMeta(ObjHeader* obj, const TypeInfo* typeInfo) {
|
||||
obj->container_offset_negative_ =
|
||||
reinterpret_cast<uintptr_t>(obj) - reinterpret_cast<uintptr_t>(currentChunk_->asHeader());
|
||||
obj->set_type_info(typeInfo);
|
||||
RuntimeAssert(obj->container() == currentChunk_->asHeader(), "Placement must match");
|
||||
}
|
||||
|
||||
ContainerChunk* currentChunk_;
|
||||
uint8_t* current_;
|
||||
uint8_t* end_;
|
||||
|
||||
@@ -63,8 +63,7 @@ inline T* PrimitiveArrayAddressOfElementAt(ArrayHeader* obj, KInt index) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const T* PrimitiveArrayAddressOfElementAt(
|
||||
const ArrayHeader* obj, KInt index) {
|
||||
inline const T* PrimitiveArrayAddressOfElementAt(const ArrayHeader* obj, KInt index) {
|
||||
return reinterpret_cast<const T*>(obj + 1) + index;
|
||||
}
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ static void initializeClass(Class clazz);
|
||||
// TODO: should we call NSObject.init ?
|
||||
UpdateRef(&result->kotlinObj, obj);
|
||||
|
||||
if (!isPermanent(obj)) {
|
||||
if (!obj->permanent()) {
|
||||
RuntimeAssert(HasAssociatedObjectField(obj), "");
|
||||
SetAssociatedObject(obj, result);
|
||||
}
|
||||
@@ -177,7 +177,7 @@ static void initializeClass(Class clazz);
|
||||
|
||||
-(instancetype)retain {
|
||||
ObjHeader* obj = kotlinObj;
|
||||
if (isPermanent(obj)) { // TODO: consider storing `isPermanent` to self field.
|
||||
if (obj->permanent()) { // TODO: consider storing `isPermanent` to self field.
|
||||
[super retain];
|
||||
} else {
|
||||
AddRefFromAssociatedObject(obj);
|
||||
@@ -187,7 +187,7 @@ static void initializeClass(Class clazz);
|
||||
|
||||
-(oneway void)release {
|
||||
ObjHeader* obj = kotlinObj;
|
||||
if (isPermanent(obj)) {
|
||||
if (obj->permanent()) {
|
||||
[super release];
|
||||
} else {
|
||||
ReleaseRefFromAssociatedObject(kotlinObj);
|
||||
@@ -195,7 +195,7 @@ static void initializeClass(Class clazz);
|
||||
}
|
||||
|
||||
-(void)releaseAsAssociatedObject {
|
||||
RuntimeAssert(!isPermanent(kotlinObj), "");
|
||||
RuntimeAssert(!kotlinObj->permanent(), "");
|
||||
[super release];
|
||||
}
|
||||
|
||||
|
||||
@@ -18,18 +18,21 @@
|
||||
|
||||
#ifdef KONAN_WASM
|
||||
namespace {
|
||||
THREAD_LOCAL_VARIABLE long long storage;
|
||||
}
|
||||
|
||||
THREAD_LOCAL_VARIABLE long long storage;
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
|
||||
KDouble ReturnSlot_getDouble() {
|
||||
return *reinterpret_cast<KDouble*>(&::storage);
|
||||
}
|
||||
|
||||
void ReturnSlot_setDouble(KInt upper, KInt lower) {
|
||||
reinterpret_cast<KInt*>(&::storage)[0] = lower;
|
||||
reinterpret_cast<KInt*>(&::storage)[1] = upper;
|
||||
}
|
||||
KDouble ReturnSlot_getDouble() {
|
||||
return *reinterpret_cast<KDouble*>(&::storage);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ReturnSlot_setDouble(KInt upper, KInt lower) {
|
||||
reinterpret_cast<KInt*>(&::storage)[0] = lower;
|
||||
reinterpret_cast<KInt*>(&::storage)[1] = upper;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
#endif // KONAN_WASM
|
||||
|
||||
@@ -17,8 +17,16 @@
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef KONAN_WASM
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
KDouble ReturnSlot_getDouble();
|
||||
void ReturnSlot_setDouble(KInt upper, KInt lower);
|
||||
}
|
||||
#endif
|
||||
|
||||
KDouble ReturnSlot_getDouble();
|
||||
void ReturnSlot_setDouble(KInt upper, KInt lower);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // KONAN_WASM
|
||||
|
||||
@@ -26,8 +26,8 @@ struct RuntimeState {
|
||||
|
||||
typedef void (*Initializer)(int initialize);
|
||||
struct InitNode {
|
||||
Initializer init;
|
||||
InitNode* next;
|
||||
Initializer init;
|
||||
InitNode* next;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
Reference in New Issue
Block a user