Minor code cleanup. (#1264)

This commit is contained in:
Nikolay Igotti
2018-01-26 20:48:21 +03:00
committed by GitHub
parent d4b47ac709
commit 12d3346c36
10 changed files with 75 additions and 78 deletions
+3 -3
View File
@@ -29,14 +29,14 @@ static inline void copyImpl(KConstRef thiz, KInt fromIndex,
const ArrayHeader* array = thiz->array(); const ArrayHeader* array = thiz->array();
ArrayHeader* destinationArray = destination->array(); ArrayHeader* destinationArray = destination->array();
if (count < 0 || if (count < 0 ||
fromIndex < 0 || count > array->count_ - fromIndex || fromIndex < 0 || count > array->count_ - fromIndex ||
toIndex < 0 || count > destinationArray->count_ - toIndex) { toIndex < 0 || count > destinationArray->count_ - toIndex) {
ThrowArrayIndexOutOfBoundsException(); ThrowArrayIndexOutOfBoundsException();
} }
memmove(PrimitiveArrayAddressOfElementAt<T>(destinationArray, toIndex), memmove(PrimitiveArrayAddressOfElementAt<T>(destinationArray, toIndex),
PrimitiveArrayAddressOfElementAt<T>(array, fromIndex), PrimitiveArrayAddressOfElementAt<T>(array, fromIndex),
count * sizeof(T)); count * sizeof(T));
} }
extern "C" { extern "C" {
+1 -5
View File
@@ -117,9 +117,7 @@ _Unwind_Reason_Code unwindCallback(
} // namespace } // namespace
#ifdef __cplusplus
extern "C" { extern "C" {
#endif
// TODO: this implementation is just a hack, e.g. the result is inexact; // 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. // however it is better to have an inexact stacktrace than not to have any.
@@ -219,6 +217,4 @@ void SetKonanTerminateHandler() {
#endif // KONAN_OBJC_INTEROP #endif // KONAN_OBJC_INTEROP
#ifdef __cplusplus } // extern "C"
} // extern "C"
#endif
-26
View File
@@ -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
+8 -8
View File
@@ -582,7 +582,7 @@ void dumpWorker(const char* prefix, ContainerHeader* header, ContainerHeaderSet*
traverseContainerReferredObjects(header, [prefix, seen](ObjHeader* ref) { traverseContainerReferredObjects(header, [prefix, seen](ObjHeader* ref) {
auto child = ref->container(); auto child = ref->container();
RuntimeAssert(!isArena(child), "A reference to local object is encountered"); 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); dumpWorker(prefix, child, seen);
} }
}); });
@@ -618,7 +618,7 @@ void MarkGray(ContainerHeader* container) {
traverseContainerReferredObjects(container, [](ObjHeader* ref) { traverseContainerReferredObjects(container, [](ObjHeader* ref) {
auto childContainer = ref->container(); auto childContainer = ref->container();
RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered"); RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered");
if (!isPermanent(childContainer)) { if (!childContainer->permanent()) {
childContainer->decRefCount(); childContainer->decRefCount();
MarkGray<useColor>(childContainer); MarkGray<useColor>(childContainer);
} }
@@ -637,7 +637,7 @@ void ScanBlack(ContainerHeader* container) {
traverseContainerReferredObjects(container, [](ObjHeader* ref) { traverseContainerReferredObjects(container, [](ObjHeader* ref) {
auto childContainer = ref->container(); auto childContainer = ref->container();
RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered"); RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered");
if (!isPermanent(childContainer)) { if (!childContainer->permanent()) {
childContainer->incRefCount(); childContainer->incRefCount();
if (useColor) { if (useColor) {
if (childContainer->color() != CONTAINER_TAG_GC_BLACK) if (childContainer->color() != CONTAINER_TAG_GC_BLACK)
@@ -701,7 +701,7 @@ void Scan(ContainerHeader* container) {
traverseContainerReferredObjects(container, [](ObjHeader* ref) { traverseContainerReferredObjects(container, [](ObjHeader* ref) {
auto childContainer = ref->container(); auto childContainer = ref->container();
RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered"); RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered");
if (!isPermanent(childContainer)) { if (!childContainer->permanent()) {
Scan(childContainer); Scan(childContainer);
} }
}); });
@@ -715,7 +715,7 @@ void CollectWhite(MemoryState* state, ContainerHeader* container) {
traverseContainerReferredObjects(container, [state](ObjHeader* ref) { traverseContainerReferredObjects(container, [state](ObjHeader* ref) {
auto childContainer = ref->container(); auto childContainer = ref->container();
RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered"); RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered");
if (!isPermanent(childContainer)) { if (!childContainer->permanent()) {
CollectWhite(state, childContainer); CollectWhite(state, childContainer);
} }
}); });
@@ -799,7 +799,7 @@ ContainerHeader* AllocContainer(size_t size) {
} }
void FreeContainer(ContainerHeader* header) { 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; auto state = memoryState;
CONTAINER_FREE_EVENT(state, header) CONTAINER_FREE_EVENT(state, header)
@@ -1080,7 +1080,7 @@ OBJ_GETTER(InitInstance,
} }
bool HasReservedObjectTail(ObjHeader* obj) { bool HasReservedObjectTail(ObjHeader* obj) {
return kObjectReservedTailSize != 0 && !isPermanent(obj); return kObjectReservedTailSize != 0 && !obj->permanent();
} }
void* GetReservedObjectTail(ObjHeader* obj) { void* GetReservedObjectTail(ObjHeader* obj) {
@@ -1300,7 +1300,7 @@ bool hasExternalRefs(ContainerHeader* container, ContainerHeaderSet* visited) {
bool result = container->refCount() != 0; bool result = container->refCount() != 0;
traverseContainerReferredObjects(container, [&result, visited](ObjHeader* ref) { traverseContainerReferredObjects(container, [&result, visited](ObjHeader* ref) {
auto child = ref->container(); auto child = ref->container();
if (!isPermanent(child) && (visited->find(child) == visited->end())) { if (!child->permanent() && (visited->find(child) == visited->end())) {
result |= hasExternalRefs(child, visited); result |= hasExternalRefs(child, visited);
} }
}); });
+31 -14
View File
@@ -24,15 +24,15 @@
// Must fit in two bits. // Must fit in two bits.
typedef enum { typedef enum {
// Those bit masks are applied to refCount_ field. // Those bit masks are applied to refCount_ field.
// Container is normal thread local container. // Container is normal thread local container.
CONTAINER_TAG_NORMAL = 0, CONTAINER_TAG_NORMAL = 0,
// Container shall be atomically refcounted, currently disabled. // Container is frozen, could only refer to other frozen objects.
// CONTAINER_TAG_SHARED = 1, // Refcounter update is atomics.
CONTAINER_TAG_FROZEN = 1,
// Those container tags shall not be refcounted. // 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, 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, CONTAINER_TAG_STACK = 3,
// Shift to get actual counter. // Shift to get actual counter.
CONTAINER_TAG_SHIFT = 2, CONTAINER_TAG_SHIFT = 2,
@@ -61,64 +61,78 @@ typedef uint32_t container_size_t;
// Header of all container objects. Contains reference counter. // Header of all container objects. Contains reference counter.
struct ContainerHeader { 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()). // for container type (for polymorphism in ::Release()).
uint32_t refCount_; uint32_t refCount_;
// Number of objects in the container. // Number of objects in the container.
uint32_t objectCount_; uint32_t objectCount_;
inline bool permanent() const {
return (refCount_ & CONTAINER_TAG_MASK) == CONTAINER_TAG_PERMANENT;
}
inline unsigned refCount() const { inline unsigned refCount() const {
return refCount_ >> CONTAINER_TAG_SHIFT; return refCount_ >> CONTAINER_TAG_SHIFT;
} }
inline void incRefCount() { inline void incRefCount() {
refCount_ += CONTAINER_TAG_INCREMENT; refCount_ += CONTAINER_TAG_INCREMENT;
} }
inline int decRefCount() { inline int decRefCount() {
refCount_ -= CONTAINER_TAG_INCREMENT; refCount_ -= CONTAINER_TAG_INCREMENT;
return refCount_ >> CONTAINER_TAG_SHIFT; return refCount_ >> CONTAINER_TAG_SHIFT;
} }
inline unsigned tag() const { inline unsigned tag() const {
return refCount_ & CONTAINER_TAG_MASK; return refCount_ & CONTAINER_TAG_MASK;
} }
inline unsigned objectCount() const { inline unsigned objectCount() const {
return objectCount_ >> CONTAINER_TAG_GC_SHIFT; return objectCount_ >> CONTAINER_TAG_GC_SHIFT;
} }
inline void incObjectCount() { inline void incObjectCount() {
objectCount_ += CONTAINER_TAG_GC_INCREMENT; objectCount_ += CONTAINER_TAG_GC_INCREMENT;
} }
inline void setObjectCount(int count) { inline void setObjectCount(int count) {
objectCount_ = count << CONTAINER_TAG_GC_SHIFT; objectCount_ = count << CONTAINER_TAG_GC_SHIFT;
} }
inline unsigned color() const { inline unsigned color() const {
return objectCount_ & CONTAINER_TAG_GC_COLOR_MASK; return objectCount_ & CONTAINER_TAG_GC_COLOR_MASK;
} }
inline void setColor(unsigned color) { inline void setColor(unsigned color) {
objectCount_ = (objectCount_ & ~CONTAINER_TAG_GC_COLOR_MASK) | color; objectCount_ = (objectCount_ & ~CONTAINER_TAG_GC_COLOR_MASK) | color;
} }
inline bool buffered() const { inline bool buffered() const {
return (objectCount_ & CONTAINER_TAG_GC_BUFFERED) != 0; return (objectCount_ & CONTAINER_TAG_GC_BUFFERED) != 0;
} }
inline void setBuffered() { inline void setBuffered() {
objectCount_ |= CONTAINER_TAG_GC_BUFFERED; objectCount_ |= CONTAINER_TAG_GC_BUFFERED;
} }
inline void resetBuffered() { inline void resetBuffered() {
objectCount_ &= ~CONTAINER_TAG_GC_BUFFERED; objectCount_ &= ~CONTAINER_TAG_GC_BUFFERED;
} }
inline bool marked() const { inline bool marked() const {
return (objectCount_ & CONTAINER_TAG_GC_MARKED) != 0; return (objectCount_ & CONTAINER_TAG_GC_MARKED) != 0;
} }
inline void mark() { inline void mark() {
objectCount_ |= CONTAINER_TAG_GC_MARKED; objectCount_ |= CONTAINER_TAG_GC_MARKED;
} }
inline void unMark() { inline void unMark() {
objectCount_ &= ~CONTAINER_TAG_GC_MARKED; objectCount_ &= ~CONTAINER_TAG_GC_MARKED;
} }
}; };
inline bool isPermanent(const ContainerHeader* header) {
return (header->refCount_ & CONTAINER_TAG_MASK) == CONTAINER_TAG_PERMANENT;
}
struct ArrayHeader; struct ArrayHeader;
// Header of every object. // Header of every object.
@@ -155,11 +169,11 @@ struct ObjHeader {
// Unsafe cast to ArrayHeader. Use carefully! // Unsafe cast to ArrayHeader. Use carefully!
ArrayHeader* array() { return reinterpret_cast<ArrayHeader*>(this); } ArrayHeader* array() { return reinterpret_cast<ArrayHeader*>(this); }
const ArrayHeader* array() const { return reinterpret_cast<const ArrayHeader*>(this); } const ArrayHeader* array() const { return reinterpret_cast<const ArrayHeader*>(this); }
};
inline bool isPermanent(const ObjHeader* obj) { inline bool permanent() const {
return isPermanent(obj->container()); return container()->permanent();
} }
};
// Header of value type array objects. Keep layout in sync with that of object header. // Header of value type array objects. Keep layout in sync with that of object header.
struct ArrayHeader { struct ArrayHeader {
@@ -280,13 +294,16 @@ class ArenaContainer {
private: private:
void* place(container_size_t size); void* place(container_size_t size);
bool allocContainer(container_size_t minSize); bool allocContainer(container_size_t minSize);
void setMeta(ObjHeader* obj, const TypeInfo* typeInfo) { void setMeta(ObjHeader* obj, const TypeInfo* typeInfo) {
obj->container_offset_negative_ = obj->container_offset_negative_ =
reinterpret_cast<uintptr_t>(obj) - reinterpret_cast<uintptr_t>(currentChunk_->asHeader()); reinterpret_cast<uintptr_t>(obj) - reinterpret_cast<uintptr_t>(currentChunk_->asHeader());
obj->set_type_info(typeInfo); obj->set_type_info(typeInfo);
RuntimeAssert(obj->container() == currentChunk_->asHeader(), "Placement must match"); RuntimeAssert(obj->container() == currentChunk_->asHeader(), "Placement must match");
} }
ContainerChunk* currentChunk_; ContainerChunk* currentChunk_;
uint8_t* current_; uint8_t* current_;
uint8_t* end_; uint8_t* end_;
+1 -2
View File
@@ -63,8 +63,7 @@ inline T* PrimitiveArrayAddressOfElementAt(ArrayHeader* obj, KInt index) {
} }
template <typename T> template <typename T>
inline const T* PrimitiveArrayAddressOfElementAt( inline const T* PrimitiveArrayAddressOfElementAt(const ArrayHeader* obj, KInt index) {
const ArrayHeader* obj, KInt index) {
return reinterpret_cast<const T*>(obj + 1) + index; return reinterpret_cast<const T*>(obj + 1) + index;
} }
+4 -4
View File
@@ -166,7 +166,7 @@ static void initializeClass(Class clazz);
// TODO: should we call NSObject.init ? // TODO: should we call NSObject.init ?
UpdateRef(&result->kotlinObj, obj); UpdateRef(&result->kotlinObj, obj);
if (!isPermanent(obj)) { if (!obj->permanent()) {
RuntimeAssert(HasAssociatedObjectField(obj), ""); RuntimeAssert(HasAssociatedObjectField(obj), "");
SetAssociatedObject(obj, result); SetAssociatedObject(obj, result);
} }
@@ -177,7 +177,7 @@ static void initializeClass(Class clazz);
-(instancetype)retain { -(instancetype)retain {
ObjHeader* obj = kotlinObj; 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]; [super retain];
} else { } else {
AddRefFromAssociatedObject(obj); AddRefFromAssociatedObject(obj);
@@ -187,7 +187,7 @@ static void initializeClass(Class clazz);
-(oneway void)release { -(oneway void)release {
ObjHeader* obj = kotlinObj; ObjHeader* obj = kotlinObj;
if (isPermanent(obj)) { if (obj->permanent()) {
[super release]; [super release];
} else { } else {
ReleaseRefFromAssociatedObject(kotlinObj); ReleaseRefFromAssociatedObject(kotlinObj);
@@ -195,7 +195,7 @@ static void initializeClass(Class clazz);
} }
-(void)releaseAsAssociatedObject { -(void)releaseAsAssociatedObject {
RuntimeAssert(!isPermanent(kotlinObj), ""); RuntimeAssert(!kotlinObj->permanent(), "");
[super release]; [super release];
} }
+14 -11
View File
@@ -18,18 +18,21 @@
#ifdef KONAN_WASM #ifdef KONAN_WASM
namespace { namespace {
THREAD_LOCAL_VARIABLE long long storage;
} THREAD_LOCAL_VARIABLE long long storage;
} // namespace
extern "C" { extern "C" {
KDouble ReturnSlot_getDouble() { KDouble ReturnSlot_getDouble() {
return *reinterpret_cast<KDouble*>(&::storage); return *reinterpret_cast<KDouble*>(&::storage);
}
void ReturnSlot_setDouble(KInt upper, KInt lower) {
reinterpret_cast<KInt*>(&::storage)[0] = lower;
reinterpret_cast<KInt*>(&::storage)[1] = upper;
}
} }
#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
+11 -3
View File
@@ -17,8 +17,16 @@
#include "Types.h" #include "Types.h"
#ifdef KONAN_WASM #ifdef KONAN_WASM
#ifdef __cplusplus
extern "C" { extern "C" {
KDouble ReturnSlot_getDouble();
void ReturnSlot_setDouble(KInt upper, KInt lower);
}
#endif #endif
KDouble ReturnSlot_getDouble();
void ReturnSlot_setDouble(KInt upper, KInt lower);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // KONAN_WASM
+2 -2
View File
@@ -26,8 +26,8 @@ struct RuntimeState {
typedef void (*Initializer)(int initialize); typedef void (*Initializer)(int initialize);
struct InitNode { struct InitNode {
Initializer init; Initializer init;
InitNode* next; InitNode* next;
}; };
namespace { namespace {