sapling/cfastmanifest/tree_arena.c
Kostia Balytskyi 918e1011b3 portability: use COMPOUND_LITERAL macro in place of actual compound literals
Summary:
This is a s//g replacement of all the `return (type_name) {` with
`return COMPOUND_LITERAL(type_name) {`.
This is the command which produced the diff:
`egrep 'return \(\w*\) \{' -Ir . --exclude='*.py*' --exclude-dir=.hg -l | xargs sed 's/return (\(\w*\)) {/return COMPOUND_LITERAL(\1) {/g' -i `

After I've done this, I checked:
`egrep '\(\w+\) \{' -Ir . --exclude='*.py*' --exclude-dir=.hg | egrep -v '(switch|while)' | grep -v 'if (' | grep -v 'COMPOUND_LITERAL' | less`
and it looks like the only things of `(something) {` syntax are function definitions, adding space before `(` in search pattern yields no results.

This is needed to make this compile on Windows under MSVC2015.

Depends on: D4843230

Test Plan:
- run `python setup.py build -f`, see it compile
- run all the tests, see them pass

Reviewers: #sourcecontrol, rmcelroy

Reviewed By: rmcelroy

Subscribers: rmcelroy, mjpieters

Differential Revision: https://phabricator.intern.facebook.com/D4843240

Signature: t1:4843240:1491495690:a097bfab403805052d5ac25d1db7bb32af3bca28
2017-04-06 09:34:40 -07:00

135 lines
4.4 KiB
C

// Copyright 2016-present Facebook. All Rights Reserved.
//
// tree_arena.c: methods to create a tree with a fixed memory arena and to
// allocate nodes from the fixed memory arena.
//
// no-check-code
#include <stdlib.h>
#include "node.h"
#include "tree.h"
#include "tree_arena.h"
#define ARENA_INCREMENT_PERCENTAGE 20
#define ARENA_MIN_STORAGE_INCREMENT (1024 * 1024)
#define ARENA_MAX_STORAGE_INCREMENT (16 * 1024 * 1024)
static inline size_t calculate_arena_free(const tree_t *tree) {
intptr_t arena_start = (intptr_t) tree->arena;
intptr_t arena_free_start = (intptr_t) tree->arena_free_start;
intptr_t arena_end = arena_start + tree->arena_sz;
size_t arena_free = arena_end - arena_free_start;
return arena_free;
}
arena_alloc_node_result_t arena_alloc_node_helper(
arena_policy_t policy,
tree_t *tree,
const char *name, size_t name_sz,
size_t max_children) {
// since name_sz and max_chlidren are going to be downcasted, we should verify
// that they're not too large for the types in node.h
if (!VERIFY_NAME_SZ(name_sz) ||
!VERIFY_CHILD_NUM(max_children)) {
return COMPOUND_LITERAL(arena_alloc_node_result_t) {
ARENA_ALLOC_EXCEEDED_LIMITS, NULL};
}
do {
size_t arena_free = calculate_arena_free(tree);
node_t *candidate = (node_t *) tree->arena_free_start;
void *next = setup_node(
tree->arena_free_start, arena_free,
name, (name_sz_t) name_sz,
(child_num_t) max_children);
if (next == NULL) {
if (policy == ARENA_POLICY_FAIL) {
return COMPOUND_LITERAL(arena_alloc_node_result_t) {
ARENA_ALLOC_OOM, NULL};
} else {
size_t new_arena_sz =
(tree->arena_sz * (100 + ARENA_INCREMENT_PERCENTAGE)) / 100;
// TODO: optimization opportunity!
// we can calculate how much free space we need and set that as another
// minimum. in the unlikely scenario we need a huge node, just setting
// the lower bound on ARENA_MIN_STORAGE_INCREMENT may require multiple
// rounds of realloc.
if (new_arena_sz - tree->arena_sz < ARENA_MIN_STORAGE_INCREMENT) {
new_arena_sz = tree->arena_sz + ARENA_MIN_STORAGE_INCREMENT;
}
if (new_arena_sz - tree->arena_sz > ARENA_MAX_STORAGE_INCREMENT) {
new_arena_sz = tree->arena_sz + ARENA_MAX_STORAGE_INCREMENT;
}
// resize the arena so it's bigger.
void *new_arena = realloc(tree->arena, new_arena_sz);
if (new_arena == NULL) {
return COMPOUND_LITERAL(arena_alloc_node_result_t) {
ARENA_ALLOC_OOM, NULL};
}
// success! update the pointers.
if (new_arena != tree->arena) {
intptr_t arena_start = (intptr_t) tree->arena;
intptr_t arena_free_start = (intptr_t) tree->arena_free_start;
intptr_t new_arena_start = (intptr_t) new_arena;
// if the shadow root is inside the arena, we need to relocate it.
if (in_arena(tree, tree->shadow_root)) {
intptr_t shadow_root = (intptr_t) tree->shadow_root;
ptrdiff_t shadow_root_offset = shadow_root - arena_start;
tree->shadow_root = (node_t *) (new_arena_start +
shadow_root_offset);
}
intptr_t new_arena_free_start = new_arena_start;
new_arena_free_start += (arena_free_start - arena_start);
tree->arena_free_start = (void *) new_arena_free_start;
tree->arena = new_arena;
}
tree->arena_sz = new_arena_sz;
}
} else {
tree->arena_free_start = next;
tree->consumed_memory += candidate->block_sz;
return COMPOUND_LITERAL(arena_alloc_node_result_t) {
ARENA_ALLOC_OK, candidate};
}
} while (true);
}
tree_t *alloc_tree_with_arena(size_t arena_sz) {
void *arena = malloc(arena_sz);
tree_t *tree = (tree_t *) calloc(1, sizeof(tree_t));
node_t *shadow_root = alloc_node("/", 1, 1);
if (arena == NULL || tree == NULL || shadow_root == NULL) {
free(arena);
free(tree);
free(shadow_root);
return NULL;
}
#if 0 // FIXME: (ttung) probably remove this
tree->mode = STANDARD_MODE;
#endif /* #if 0 */
tree->arena = tree->arena_free_start = arena;
tree->arena_sz = arena_sz;
tree->compacted = true;
tree->shadow_root = NULL;
tree->consumed_memory = 0;
tree->num_leaf_nodes = 0;
shadow_root->type = TYPE_ROOT;
tree->shadow_root = shadow_root;
return tree;
}