4
* Copyright Ericsson AB 1996-2009. All Rights Reserved.
4
* Copyright Ericsson AB 1996-2011. All Rights Reserved.
6
6
* The contents of this file are subject to the Erlang Public License,
7
7
* Version 1.1, (the "License"); you may not use this file except in
8
8
* compliance with the License. You should have received a copy of the
9
9
* Erlang Public License along with this software. If not, it can be
10
10
* retrieved online at http://www.erlang.org/.
12
12
* Software distributed under the License is distributed on an "AS IS"
13
13
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
* the License for the specific language governing rights and limitations
15
15
* under the License.
103
#ifdef FORCE_HEAP_FRAGS
104
if (p->space_verified && p->space_verified_from!=NULL
105
&& HEAP_TOP(p) >= p->space_verified_from
106
&& HEAP_TOP(p) + need <= p->space_verified_from + p->space_verified
107
&& HEAP_LIMIT(p) - HEAP_TOP(p) >= need) {
109
Uint consumed = need + (HEAP_TOP(p) - p->space_verified_from);
110
ASSERT(consumed <= p->space_verified);
111
p->space_verified -= consumed;
112
p->space_verified_from += consumed;
113
HEAP_TOP(p) = p->space_verified_from;
114
return HEAP_TOP(p) - need;
116
p->space_verified = 0;
117
p->space_verified_from = NULL;
118
#endif /* FORCE_HEAP_FRAGS */
122
if (bp != NULL && need <= (bp->alloc_size - bp->used_size)) {
123
Eterm* ret = bp->mem + bp->used_size;
124
bp->used_size += need;
112
130
bp = (ErlHeapFragment*)
113
ERTS_HEAP_ALLOC(ERTS_ALC_T_HEAP_FRAG,
114
sizeof(ErlHeapFragment) + ((n-1)*sizeof(Eterm)));
131
ERTS_HEAP_ALLOC(ERTS_ALC_T_HEAP_FRAG, ERTS_HEAP_FRAG_SIZE(n));
133
#if defined(DEBUG) || defined(CHECK_FOR_HOLES)
134
for (i = 0; i < n; i++) {
135
bp->mem[i] = ERTS_HOLE_MARKER;
121
for (i = 0; i <= n; i++) {
122
bp->mem[i] = ERTS_HOLE_MARKER;
124
#elif defined(CHECK_FOR_HOLES)
125
for (i = 0; i < n; i++) {
126
bp->mem[i] = ERTS_HOLE_MARKER;
131
144
* When we have created a heap fragment, we are no longer allowed
132
145
* to store anything more on the heap.
140
153
bp->next = MBUF(p);
156
bp->used_size = need;
143
157
MBUF_SIZE(p) += n;
144
bp->off_heap.mso = NULL;
145
#ifndef HYBRID /* FIND ME! */
146
bp->off_heap.funs = NULL;
148
bp->off_heap.externals = NULL;
158
bp->off_heap.first = NULL;
149
159
bp->off_heap.overhead = 0;
154
void erts_arith_shrink(Process* p, Eterm* hp)
156
#if defined(CHECK_FOR_HOLES)
160
* We must find the heap fragment that hp points into.
161
* If we are unlucky, we might have to search through
162
* a large part of the list. We'll hope that will not
165
for (hf = MBUF(p); hf != 0; hf = hf->next) {
166
if (hp - hf->mem < (unsigned long)hf->size) {
168
* We are not allowed to changed hf->size (because the
169
* size must be correct when deallocating). Therefore,
170
* clear out the uninitialized part of the heap fragment.
172
Eterm* to = hf->mem + hf->size;
182
163
#ifdef CHECK_FOR_HOLES
184
165
erts_set_hole_marker(Eterm* ptr, Uint sz)
212
193
*end = *start + new_size;
213
194
*sp = *start + sp_offs;
197
* Helper function for the ESTACK macros defined in global.h.
200
erl_grow_wstack(UWord** start, UWord** sp, UWord** end)
202
Uint old_size = (*end - *start);
203
Uint new_size = old_size * 2;
204
Uint sp_offs = *sp - *start;
205
if (new_size > 2 * DEF_ESTACK_SIZE) {
206
*start = erts_realloc(ERTS_ALC_T_ESTACK, (void *) *start, new_size*sizeof(UWord));
208
UWord* new_ptr = erts_alloc(ERTS_ALC_T_ESTACK, new_size*sizeof(UWord));
209
sys_memcpy(new_ptr, *start, old_size*sizeof(UWord));
212
*end = *start + new_size;
213
*sp = *start + sp_offs;
216
216
/* CTYPE macros */
366
* Erts_bld_uword is more or less similar to erts_bld_uint, but a pointer
367
* can safely be passed.
371
erts_bld_uword(Uint **hpp, Uint *szp, UWord uw)
373
Eterm res = THE_NON_VALUE;
374
if (IS_USMALL(0, uw)) {
376
res = make_small((Uint) uw);
380
*szp += BIG_UWORD_HEAP_SIZE(uw);
382
res = uword_to_big(uw, *hpp);
383
*hpp += BIG_UWORD_HEAP_SIZE(uw);
366
391
erts_bld_uint64(Uint **hpp, Uint *szp, Uint64 ui64)
862
887
hash = hash*FUNNY_NUMBER2 + unsigned_val(*list);
864
889
if (is_not_list(CDR(list))) {
865
ESTACK_PUSH(stack, MAKE_HASH_CDR_POST_OP);
890
WSTACK_PUSH(stack, MAKE_HASH_CDR_POST_OP);
866
891
term = CDR(list);
869
894
list = list_val(CDR(list));
871
ESTACK_PUSH2(stack, CDR(list), MAKE_HASH_CDR_PRE_OP);
896
WSTACK_PUSH2(stack, CDR(list), MAKE_HASH_CDR_PRE_OP);
872
897
term = CAR(list);
912
937
Eterm* ptr = tuple_val(term);
913
938
Uint arity = arityval(*ptr);
915
ESTACK_PUSH3(stack, arity, (Eterm)(ptr+1), arity);
940
WSTACK_PUSH3(stack, (UWord) arity, (UWord)(ptr+1), (UWord) arity);
916
941
op = MAKE_HASH_TUPLE_OP;
917
942
}/*fall through*/
918
943
case MAKE_HASH_TUPLE_OP:
919
944
case MAKE_HASH_FUN_OP:
921
Uint i = ESTACK_POP(stack);
922
Eterm* ptr = (Eterm*) ESTACK_POP(stack);
946
Uint i = (Uint) WSTACK_POP(stack);
947
Eterm* ptr = (Eterm*) WSTACK_POP(stack);
925
ESTACK_PUSH3(stack, (Eterm)(ptr+1), i-1, op);
950
WSTACK_PUSH3(stack, (UWord)(ptr+1), (UWord) i-1, (UWord) op);
928
953
if (op == MAKE_HASH_TUPLE_OP) {
929
Uint32 arity = ESTACK_POP(stack);
954
Uint32 arity = (Uint32) WSTACK_POP(stack);
930
955
hash = hash*FUNNY_NUMBER9 + arity;
1466
1492
case MAKE_HASH_CDR_PRE_OP:
1467
term = ESTACK_POP(stack);
1493
term = (Eterm) WSTACK_POP(stack);
1468
1494
if (is_not_list(term)) {
1469
ESTACK_PUSH(stack, MAKE_HASH_CDR_POST_OP);
1495
WSTACK_PUSH(stack, (UWord) MAKE_HASH_CDR_POST_OP);
1470
1496
goto tail_recur;
1472
1498
/*fall through*/
1475
1501
Eterm* list = list_val(term);
1476
ESTACK_PUSH2(stack, CDR(list), MAKE_HASH_CDR_PRE_OP);
1502
WSTACK_PUSH2(stack, (UWord) CDR(list),
1503
(UWord) MAKE_HASH_CDR_PRE_OP);
1477
1504
term = CAR(list);
1478
1505
goto tail_recur;
1546
1573
Eterm* ptr = tuple_val(term);
1547
1574
Uint arity = arityval(*ptr);
1549
ESTACK_PUSH3(stack, arity, (Eterm)(ptr+1), arity);
1576
WSTACK_PUSH3(stack, (UWord) arity, (UWord) (ptr+1), (UWord) arity);
1550
1577
op = MAKE_HASH_TUPLE_OP;
1551
1578
}/*fall through*/
1552
1579
case MAKE_HASH_TUPLE_OP:
1553
1580
case MAKE_HASH_FUN_OP:
1555
Uint i = ESTACK_POP(stack);
1556
Eterm* ptr = (Eterm*) ESTACK_POP(stack);
1582
Uint i = (Uint) WSTACK_POP(stack);
1583
Eterm* ptr = (Eterm*) WSTACK_POP(stack);
1559
ESTACK_PUSH3(stack, (Eterm)(ptr+1), i-1, op);
1586
WSTACK_PUSH3(stack, (UWord)(ptr+1), (UWord) i-1, (UWord) op);
1560
1587
goto tail_recur;
1562
1589
if (op == MAKE_HASH_TUPLE_OP) {
1563
Uint32 arity = ESTACK_POP(stack);
1590
Uint32 arity = (UWord) WSTACK_POP(stack);
1564
1591
hash = hash*FUNNY_NUMBER9 + arity;
1867
1894
erts_free(ERTS_ALC_T_TMP_DSBUF, (void *) dsbufp);
1871
1897
/* eq and cmp are written as separate functions a eq is a little faster */
1874
1900
* Test for equality of two terms.
1875
1901
* Returns 0 if not equal, or a non-zero value otherwise.
1904
int eq_rel(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base)
1878
1906
int eq(Eterm a, Eterm b)
1880
DECLARE_ESTACK(stack);
1909
DECLARE_WSTACK(stack);
1886
if (a == b) goto pop_next;
1915
if (is_same(a, a_base, b, b_base)) goto pop_next;
1889
1918
switch (primary_tag(a)) {
1890
1919
case TAG_PRIMARY_LIST:
1891
1920
if (is_list(b)) {
1892
Eterm* aval = list_val(a);
1893
Eterm* bval = list_val(b);
1921
Eterm* aval = list_val_rel(a, a_base);
1922
Eterm* bval = list_val_rel(b, b_base);
1895
1924
Eterm atmp = CAR(aval);
1896
1925
Eterm btmp = CAR(bval);
1898
ESTACK_PUSH2(stack,CDR(bval),CDR(aval));
1926
if (!is_same(atmp,a_base,btmp,b_base)) {
1927
WSTACK_PUSH2(stack,(UWord) CDR(bval),(UWord) CDR(aval));
1901
1930
goto tailrecur_ne;
1903
1932
atmp = CDR(aval);
1904
1933
btmp = CDR(bval);
1934
if (is_same(atmp,a_base,btmp,b_base)) {
1908
1937
if (is_not_list(atmp) || is_not_list(btmp)) {
1911
1940
goto tailrecur_ne;
1913
aval = list_val(atmp);
1914
bval = list_val(btmp);
1942
aval = list_val_rel(atmp, a_base);
1943
bval = list_val_rel(btmp, b_base);
1917
1946
break; /* not equal */
1919
1948
case TAG_PRIMARY_BOXED:
1921
Eterm hdr = *boxed_val(a);
1950
Eterm hdr = *boxed_val_rel(a,a_base);
1922
1951
switch (hdr & _TAG_HEADER_MASK) {
1923
1952
case ARITYVAL_SUBTAG:
1926
if (!is_boxed(b) || *boxed_val(b) != *aa)
1954
aa = tuple_val_rel(a, a_base);
1955
if (!is_boxed(b) || *boxed_val_rel(b,b_base) != *aa)
1927
1956
goto not_equal;
1957
bb = tuple_val_rel(b,b_base);
1929
1958
if ((sz = arityval(*aa)) == 0) goto pop_next;
1944
1973
Uint a_bitoffs;
1945
1974
Uint b_bitoffs;
1947
if (is_not_binary(b)) {
1976
if (!is_binary_rel(b,b_base)) {
1948
1977
goto not_equal;
1950
a_size = binary_size(a);
1951
b_size = binary_size(b);
1979
a_size = binary_size_rel(a,a_base);
1980
b_size = binary_size_rel(b,b_base);
1952
1981
if (a_size != b_size) {
1953
1982
goto not_equal;
1955
ERTS_GET_BINARY_BYTES(a, a_ptr, a_bitoffs, a_bitsize);
1956
ERTS_GET_BINARY_BYTES(b, b_ptr, b_bitoffs, b_bitsize);
1984
ERTS_GET_BINARY_BYTES_REL(a, a_ptr, a_bitoffs, a_bitsize, a_base);
1985
ERTS_GET_BINARY_BYTES_REL(b, b_ptr, b_bitoffs, b_bitsize, b_base);
1957
1986
if ((a_bitsize | b_bitsize | a_bitoffs | b_bitoffs) == 0) {
1958
1987
if (sys_memcmp(a_ptr, b_ptr, a_size) == 0) goto pop_next;
1959
1988
} else if (a_bitsize == b_bitsize) {
1976
2005
ErlFunThing* f1;
1977
2006
ErlFunThing* f2;
2008
if (!is_fun_rel(b,b_base))
1980
2009
goto not_equal;
1981
f1 = (ErlFunThing *) fun_val(a);
1982
f2 = (ErlFunThing *) fun_val(b);
2010
f1 = (ErlFunThing *) fun_val_rel(a,a_base);
2011
f2 = (ErlFunThing *) fun_val_rel(b,b_base);
1983
2012
if (f1->fe->module != f2->fe->module ||
1984
2013
f1->fe->old_index != f2->fe->old_index ||
1985
2014
f1->fe->old_uniq != f2->fe->old_uniq ||
1997
2026
ExternalThing *ap;
1998
2027
ExternalThing *bp;
2000
if(is_not_external(b))
2029
if(!is_external_rel(b,b_base))
2001
2030
goto not_equal;
2003
ap = external_thing_ptr(a);
2004
bp = external_thing_ptr(b);
2032
ap = external_thing_ptr_rel(a,a_base);
2033
bp = external_thing_ptr_rel(b,b_base);
2006
2035
if(ap->header == bp->header && ap->node == bp->node) {
2007
ASSERT(1 == external_data_words(a));
2008
ASSERT(1 == external_data_words(b));
2036
ASSERT(1 == external_data_words_rel(a,a_base));
2037
ASSERT(1 == external_data_words_rel(b,b_base));
2010
2039
if (ap->data.ui[0] == bp->data.ui[0]) goto pop_next;
2027
if(is_not_external_ref(b))
2030
if(external_node(a) != external_node(b))
2033
anum = external_ref_numbers(a);
2034
bnum = external_ref_numbers(b);
2035
alen = external_ref_no_of_numbers(a);
2036
blen = external_ref_no_of_numbers(b);
2055
ExternalThing* athing;
2056
ExternalThing* bthing;
2058
if(!is_external_ref_rel(b,b_base))
2061
athing = external_thing_ptr_rel(a,a_base);
2062
bthing = external_thing_ptr_rel(b,b_base);
2064
if(athing->node != bthing->node)
2067
anum = external_thing_ref_numbers(athing);
2068
bnum = external_thing_ref_numbers(bthing);
2069
alen = external_thing_ref_no_of_numbers(athing);
2070
blen = external_thing_ref_no_of_numbers(bthing);
2038
2072
goto ref_common;
2039
2073
case REF_SUBTAG:
2041
if (is_not_internal_ref(b))
2074
if (!is_internal_ref_rel(b,b_base))
2042
2075
goto not_equal;
2043
alen = internal_ref_no_of_numbers(a);
2044
blen = internal_ref_no_of_numbers(b);
2045
anum = internal_ref_numbers(a);
2046
bnum = internal_ref_numbers(b);
2078
RefThing* athing = ref_thing_ptr_rel(a,a_base);
2079
RefThing* bthing = ref_thing_ptr_rel(b,b_base);
2080
alen = internal_thing_ref_no_of_numbers(athing);
2081
blen = internal_thing_ref_no_of_numbers(bthing);
2082
anum = internal_thing_ref_numbers(athing);
2083
bnum = internal_thing_ref_numbers(bthing);
2049
2087
ASSERT(alen > 0 && blen > 0);
2138
2176
goto not_equal;
2140
2178
if (i > 1) { /* push the rest */
2141
ESTACK_PUSH3(stack, i-1, (Eterm)(bp+1),
2142
((Eterm)(ap+1)) | TAG_PRIMARY_HEADER);
2179
WSTACK_PUSH3(stack, i-1, (UWord)(bp+1),
2180
((UWord)(ap+1)) | TAG_PRIMARY_HEADER);
2143
2181
/* We (ab)use TAG_PRIMARY_HEADER to recognize a term_array */
2145
2183
goto tailrecur_ne;
2149
if (!ESTACK_ISEMPTY(stack)) {
2150
Eterm something = ESTACK_POP(stack);
2151
if (primary_tag(something) == TAG_PRIMARY_HEADER) { /* a term_array */
2187
if (!WSTACK_ISEMPTY(stack)) {
2188
UWord something = WSTACK_POP(stack);
2189
if (primary_tag((Eterm) something) == TAG_PRIMARY_HEADER) { /* a term_array */
2152
2190
aa = (Eterm*) something;
2153
bb = (Eterm*) ESTACK_POP(stack);
2154
sz = ESTACK_POP(stack);
2191
bb = (Eterm*) WSTACK_POP(stack);
2192
sz = WSTACK_POP(stack);
2155
2193
goto term_array;
2158
b = ESTACK_POP(stack);
2196
b = WSTACK_POP(stack);
2159
2197
goto tailrecur;
2162
DESTROY_ESTACK(stack);
2200
DESTROY_WSTACK(stack);
2166
DESTROY_ESTACK(stack);
2204
DESTROY_WSTACK(stack);
2276
2318
if (is_internal_port(b)) {
2277
2319
bnode = erts_this_node;
2278
2320
bdata = internal_port_data(b);
2279
} else if (is_external_port(b)) {
2280
bnode = external_port_node(b);
2281
bdata = external_port_data(b);
2321
} else if (is_external_port_rel(b,b_base)) {
2322
bnode = external_port_node_rel(b,b_base);
2323
bdata = external_port_data_rel(b,b_base);
2283
2325
a_tag = PORT_DEF;
2284
2326
goto mixed_types;
2294
2336
if (is_internal_pid(b)) {
2295
2337
bnode = erts_this_node;
2296
2338
bdata = internal_pid_data(b);
2297
} else if (is_external_pid(b)) {
2298
bnode = external_pid_node(b);
2299
bdata = external_pid_data(b);
2339
} else if (is_external_pid_rel(b,b_base)) {
2340
bnode = external_pid_node_rel(b,b_base);
2341
bdata = external_pid_data_rel(b,b_base);
2301
2343
a_tag = PID_DEF;
2302
2344
goto mixed_types;
2329
2371
a_tag = LIST_DEF;
2330
2372
goto mixed_types;
2374
aa = list_val_rel(a,a_base);
2375
bb = list_val_rel(b,b_base);
2335
2377
Eterm atmp = CAR(aa);
2336
2378
Eterm btmp = CAR(bb);
2338
ESTACK_PUSH2(stack,CDR(bb),CDR(aa));
2379
if (!is_same(atmp,a_base,btmp,b_base)) {
2380
WSTACK_PUSH2(stack,(UWord) CDR(bb),(UWord) CDR(aa));
2341
2383
goto tailrecur_ne;
2343
2385
atmp = CDR(aa);
2344
2386
btmp = CDR(bb);
2387
if (is_same(atmp,a_base,btmp,b_base)) {
2348
2390
if (is_not_list(atmp) || is_not_list(btmp)) {
2351
2393
goto tailrecur_ne;
2353
aa = list_val(atmp);
2354
bb = list_val(btmp);
2395
aa = list_val_rel(atmp,a_base);
2396
bb = list_val_rel(btmp,b_base);
2356
2398
case TAG_PRIMARY_BOXED:
2358
Eterm ahdr = *boxed_val(a);
2400
Eterm ahdr = *boxed_val_rel(a,a_base);
2359
2401
switch ((ahdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
2360
2402
case (_TAG_HEADER_ARITYVAL >> _TAG_PRIMARY_SIZE):
2361
if (is_not_tuple(b)) {
2403
if (!is_tuple_rel(b,b_base)) {
2362
2404
a_tag = TUPLE_DEF;
2363
2405
goto mixed_types;
2407
aa = tuple_val_rel(a,a_base);
2408
bb = tuple_val_rel(b,b_base);
2367
2409
/* compare the arities */
2368
2410
i = arityval(ahdr); /* get the arity*/
2369
2411
if (i != arityval(*bb)) {
2377
2419
goto term_array;
2379
2421
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
2380
if (is_not_float(b)) {
2422
if (!is_float_rel(b,b_base)) {
2381
2423
a_tag = FLOAT_DEF;
2382
2424
goto mixed_types;
2429
GET_DOUBLE_REL(a, af, a_base);
2430
GET_DOUBLE_REL(b, bf, b_base);
2389
2431
ON_CMP_GOTO(float_comp(af.fd, bf.fd));
2391
2433
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
2392
2434
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
2393
if (is_not_big(b)) {
2435
if (!is_big_rel(b,b_base)) {
2394
2436
a_tag = BIG_DEF;
2395
2437
goto mixed_types;
2397
ON_CMP_GOTO(big_comp(a, b));
2439
ON_CMP_GOTO(big_comp(rterm2wterm(a,a_base), rterm2wterm(b,b_base)));
2398
2440
case (_TAG_HEADER_EXPORT >> _TAG_PRIMARY_SIZE):
2399
if (is_not_export(b)) {
2441
if (!is_export_rel(b,b_base)) {
2400
2442
a_tag = EXPORT_DEF;
2401
2443
goto mixed_types;
2403
Export* a_exp = (Export *) (export_val(a))[1];
2404
Export* b_exp = (Export *) (export_val(b))[1];
2445
Export* a_exp = *((Export **) (export_val_rel(a,a_base) + 1));
2446
Export* b_exp = *((Export **) (export_val_rel(b,b_base) + 1));
2406
2448
if ((j = cmp_atoms(a_exp->code[0], b_exp->code[0])) != 0) {
2415
2457
case (_TAG_HEADER_FUN >> _TAG_PRIMARY_SIZE):
2416
if (is_not_fun(b)) {
2458
if (!is_fun_rel(b,b_base)) {
2417
2459
a_tag = FUN_DEF;
2418
2460
goto mixed_types;
2420
ErlFunThing* f1 = (ErlFunThing *) fun_val(a);
2421
ErlFunThing* f2 = (ErlFunThing *) fun_val(b);
2462
ErlFunThing* f1 = (ErlFunThing *) fun_val_rel(a,a_base);
2463
ErlFunThing* f2 = (ErlFunThing *) fun_val_rel(b,b_base);
2424
2466
diff = cmpbytes(atom_tab(atom_val(f1->fe->module))->name,
2450
2492
if (is_internal_pid(b)) {
2451
2493
bnode = erts_this_node;
2452
2494
bdata = internal_pid_data(b);
2453
} else if (is_external_pid(b)) {
2454
bnode = external_pid_node(b);
2455
bdata = external_pid_data(b);
2495
} else if (is_external_pid_rel(b,b_base)) {
2496
bnode = external_pid_node_rel(b,b_base);
2497
bdata = external_pid_data_rel(b,b_base);
2457
2499
a_tag = EXTERNAL_PID_DEF;
2458
2500
goto mixed_types;
2460
anode = external_pid_node(a);
2461
adata = external_pid_data(a);
2502
anode = external_pid_node_rel(a,a_base);
2503
adata = external_pid_data_rel(a,a_base);
2462
2504
goto pid_common;
2463
2505
case (_TAG_HEADER_EXTERNAL_PORT >> _TAG_PRIMARY_SIZE):
2464
2506
if (is_internal_port(b)) {
2465
2507
bnode = erts_this_node;
2466
2508
bdata = internal_port_data(b);
2467
} else if (is_external_port(b)) {
2468
bnode = external_port_node(b);
2469
bdata = external_port_data(b);
2509
} else if (is_external_port_rel(b,b_base)) {
2510
bnode = external_port_node_rel(b,b_base);
2511
bdata = external_port_data_rel(b,b_base);
2471
2513
a_tag = EXTERNAL_PORT_DEF;
2472
2514
goto mixed_types;
2474
anode = external_port_node(a);
2475
adata = external_port_data(a);
2516
anode = external_port_node_rel(a,a_base);
2517
adata = external_port_data_rel(a,a_base);
2476
2518
goto port_common;
2477
2519
case (_TAG_HEADER_REF >> _TAG_PRIMARY_SIZE):
2479
2521
* Note! When comparing refs we need to compare ref numbers
2480
2522
* (32-bit words), *not* ref data words.
2483
if (is_internal_ref(b)) {
2526
if (is_internal_ref_rel(b,b_base)) {
2527
RefThing* bthing = ref_thing_ptr_rel(b,b_base);
2484
2528
bnode = erts_this_node;
2485
bnum = internal_ref_numbers(b);
2486
blen = internal_ref_no_of_numbers(b);
2487
} else if(is_external_ref(b)) {
2488
bnode = external_ref_node(b);
2489
bnum = external_ref_numbers(b);
2490
blen = external_ref_no_of_numbers(b);
2529
bnum = internal_thing_ref_numbers(bthing);
2530
blen = internal_thing_ref_no_of_numbers(bthing);
2531
} else if(is_external_ref_rel(b,b_base)) {
2532
ExternalThing* bthing = external_thing_ptr_rel(b,b_base);
2533
bnode = bthing->node;
2534
bnum = external_thing_ref_numbers(bthing);
2535
blen = external_thing_ref_no_of_numbers(bthing);
2492
2537
a_tag = REF_DEF;
2493
2538
goto mixed_types;
2495
anode = erts_this_node;
2496
anum = internal_ref_numbers(a);
2497
alen = internal_ref_no_of_numbers(a);
2541
RefThing* athing = ref_thing_ptr_rel(a,a_base);
2542
anode = erts_this_node;
2543
anum = internal_thing_ref_numbers(athing);
2544
alen = internal_thing_ref_no_of_numbers(athing);
2500
2548
CMP_NODES(anode, bnode);
2523
2571
RETURN_NEQ((Sint32) (anum[i] - bnum[i]));
2525
2573
case (_TAG_HEADER_EXTERNAL_REF >> _TAG_PRIMARY_SIZE):
2526
if (is_internal_ref(b)) {
2574
if (is_internal_ref_rel(b,b_base)) {
2575
RefThing* bthing = ref_thing_ptr_rel(b,b_base);
2527
2576
bnode = erts_this_node;
2528
bnum = internal_ref_numbers(b);
2529
blen = internal_ref_no_of_numbers(b);
2530
} else if (is_external_ref(b)) {
2531
bnode = external_ref_node(b);
2532
bnum = external_ref_numbers(b);
2533
blen = external_ref_no_of_numbers(b);
2577
bnum = internal_thing_ref_numbers(bthing);
2578
blen = internal_thing_ref_no_of_numbers(bthing);
2579
} else if (is_external_ref_rel(b,b_base)) {
2580
ExternalThing* bthing = external_thing_ptr_rel(b,b_base);
2581
bnode = bthing->node;
2582
bnum = external_thing_ref_numbers(bthing);
2583
blen = external_thing_ref_no_of_numbers(bthing);
2535
2585
a_tag = EXTERNAL_REF_DEF;
2536
2586
goto mixed_types;
2538
anode = external_ref_node(a);
2539
anum = external_ref_numbers(a);
2540
alen = external_ref_no_of_numbers(a);
2589
ExternalThing* athing = external_thing_ptr_rel(a,a_base);
2590
anode = athing->node;
2591
anum = external_thing_ref_numbers(athing);
2592
alen = external_thing_ref_no_of_numbers(athing);
2541
2594
goto ref_common;
2543
2596
/* Must be a binary */
2544
ASSERT(is_binary(a));
2545
if (is_not_binary(b)) {
2597
ASSERT(is_binary_rel(a,a_base));
2598
if (!is_binary_rel(b,b_base)) {
2546
2599
a_tag = BINARY_DEF;
2547
2600
goto mixed_types;
2549
Uint a_size = binary_size(a);
2550
Uint b_size = binary_size(b);
2602
Uint a_size = binary_size_rel(a,a_base);
2603
Uint b_size = binary_size_rel(b,b_base);
2551
2604
Uint a_bitsize;
2552
2605
Uint b_bitsize;
2553
2606
Uint a_bitoffs;
2559
ERTS_GET_BINARY_BYTES(a, a_ptr, a_bitoffs, a_bitsize);
2560
ERTS_GET_BINARY_BYTES(b, b_ptr, b_bitoffs, b_bitsize);
2612
ERTS_GET_BINARY_BYTES_REL(a, a_ptr, a_bitoffs, a_bitsize, a_base);
2613
ERTS_GET_BINARY_BYTES_REL(b, b_ptr, b_bitoffs, b_bitsize, b_base);
2561
2614
if ((a_bitsize | b_bitsize | a_bitoffs | b_bitoffs) == 0) {
2562
2615
min_size = (a_size < b_size) ? a_size : b_size;
2563
2616
if ((cmp = sys_memcmp(a_ptr, b_ptr, min_size)) != 0) {
2587
b_tag = tag_val_def(b);
2590
2642
FloatDef f1, f2;
2645
Eterm big_buf[2]; /* If HEAP_ON_C_STACK */
2647
Eterm *big_buf = erts_get_scheduler_data()->cmp_tmp_heap;
2650
Wterm aw = is_immed(a) ? a : rterm2wterm(a,a_base);
2651
Wterm bw = is_immed(b) ? b : rterm2wterm(b,b_base);
2656
b_tag = tag_val_def(bw);
2594
2658
switch(_NUMBER_CODE(a_tag, b_tag)) {
2595
2659
case SMALL_BIG:
2596
2660
big = small_to_big(signed_val(a), big_buf);
2597
j = big_comp(big, b);
2661
j = big_comp(big, bw);
2599
2663
case SMALL_FLOAT:
2600
2664
f1.fd = signed_val(a);
2602
2666
j = float_comp(f1.fd, f2.fd);
2604
2668
case BIG_SMALL:
2605
2669
big = small_to_big(signed_val(b), big_buf);
2606
j = big_comp(a, big);
2670
j = big_comp(aw, big);
2608
2672
case BIG_FLOAT:
2609
if (big_to_double(a, &f1.fd) < 0) {
2673
if (big_to_double(aw, &f1.fd) < 0) {
2610
2674
j = big_sign(a) ? -1 : 1;
2613
2677
j = float_comp(f1.fd, f2.fd);
2616
2680
case FLOAT_SMALL:
2618
2682
f2.fd = signed_val(b);
2619
2683
j = float_comp(f1.fd, f2.fd);
2621
2685
case FLOAT_BIG:
2622
if (big_to_double(b, &f2.fd) < 0) {
2686
if (big_to_double(bw, &f2.fd) < 0) {
2623
2687
j = big_sign(b) ? 1 : -1;
2626
2690
j = float_comp(f1.fd, f2.fd);
2662
2726
goto tailrecur;
2665
if (!ESTACK_ISEMPTY(stack)) {
2666
Eterm something = ESTACK_POP(stack);
2667
if (primary_tag(something) == TAG_PRIMARY_HEADER) { /* a term_array */
2729
if (!WSTACK_ISEMPTY(stack)) {
2730
UWord something = WSTACK_POP(stack);
2731
if (primary_tag((Eterm) something) == TAG_PRIMARY_HEADER) { /* a term_array */
2668
2732
aa = (Eterm*) something;
2669
bb = (Eterm*) ESTACK_POP(stack);
2670
i = ESTACK_POP(stack);
2733
bb = (Eterm*) WSTACK_POP(stack);
2734
i = WSTACK_POP(stack);
2671
2735
goto term_array;
2674
b = ESTACK_POP(stack);
2737
a = (Eterm) something;
2738
b = (Eterm) WSTACK_POP(stack);
2675
2739
goto tailrecur;
2678
DESTROY_ESTACK(stack);
2742
DESTROY_WSTACK(stack);
3615
static ERTS_INLINE int
3666
static ERTS_INLINE erts_aint32_t
3616
3667
threads_not_under_control(void)
3618
int res = system_block_state.threads_to_block;
3669
erts_aint32_t res = system_block_state.threads_to_block;
3620
3671
/* Waiting is always an allowed activity... */
3621
res -= erts_smp_atomic_read(&erts_system_block_state.in_activity.wait);
3672
res -= erts_smp_atomic32_read(&erts_system_block_state.in_activity.wait);
3623
3674
if (system_block_state.allowed_activities & ERTS_BS_FLG_ALLOW_GC)
3624
res -= erts_smp_atomic_read(&erts_system_block_state.in_activity.gc);
3675
res -= erts_smp_atomic32_read(&erts_system_block_state.in_activity.gc);
3626
3677
if (system_block_state.allowed_activities & ERTS_BS_FLG_ALLOW_IO)
3627
res -= erts_smp_atomic_read(&erts_system_block_state.in_activity.io);
3678
res -= erts_smp_atomic32_read(&erts_system_block_state.in_activity.io);
3933
3984
/* Global state... */
3935
erts_smp_atomic_init(&erts_system_block_state.do_block, 0L);
3936
erts_smp_atomic_init(&erts_system_block_state.in_activity.wait, 0L);
3937
erts_smp_atomic_init(&erts_system_block_state.in_activity.gc, 0L);
3938
erts_smp_atomic_init(&erts_system_block_state.in_activity.io, 0L);
3986
erts_smp_atomic32_init(&erts_system_block_state.do_block, 0);
3987
erts_smp_atomic32_init(&erts_system_block_state.in_activity.wait, 0);
3988
erts_smp_atomic32_init(&erts_system_block_state.in_activity.gc, 0);
3989
erts_smp_atomic32_init(&erts_system_block_state.in_activity.io, 0);
3940
3991
/* Make sure blockable threads unregister when exiting... */
3941
3992
erts_smp_install_exit_handler(erts_unregister_blockable_thread);