CS 208 w20 lecture 25 outline
Request | VPN | TLBT | TLBI | TLB hit? | page fault? | PPN | CT | CI | CO | cache hit? | data (byte) |
0x03d4 |
0x0f |
0x03 |
3 |
yes | no | 0x0d |
0x0d |
5 |
0 |
yes | 0x36 |
0x038f |
0x0e |
0x03 |
2 |
no | yes | - | - | - | - | - | - |
0x0020 |
0x00 |
0x00 |
0 |
no | no | 0x28 |
0x28 |
8 |
0 |
no | - |
0x036b |
0x0d |
0x03 |
1 |
yes | no | 0x2d |
0x2d |
a |
3 |
yes | 0x3b |
1 Multi-Level Page Tables
- suppose 64-bit virtual addresses (\(n=64\)), 8 KB pages (\(p=13\)), 8 GB physical memory (\(m=33\))
- how many page table entries? 2n-p = 251
- how many bits per PTE? PPN width + management bits = \(m - p + 5\) (valid, dirty, read, write, execute) = 25 bits or about 3 bytes
- we can't actually have 4 million GB worth of page table entries for each process
- we can use multi-level page tables to reduce memory overhead
- VPN split into \(k\) segments, one for each level of page table
- instead of a million page table entries in memory, most unused, we have have a level 1 table with 1000 entries, and then only have a second level of 1000 for allocated level 1 entries
2 Java vs C
- integers, floats, doubles, pointers have the same representation as C
- pointers are called references in Java, much more constrained
- Java specification fixes the sizes of all types
- e.g.,
long
is 64 bits regardless of machine
- e.g.,
2.1 Arrays
- initialize elements
- keep length in immutable field (
array.length
) - every access triggers a bounds check
- exception if access is out-of-bounds (a Java exception, not an OS exception)
- will checking the array length as part of a loop be a big performance hit?
2.2 Strings
- Java uses two-byte Unicode instead of ASCII
- can represent most of the world's alphabets
- no null terminator
String
objects are read-only
2.3 Objects
- data structures always stored by reference, never inline
- virtual method table (vtable) provides pointers to class methods
- each instance stores a pointer to its vtable
3 Common Memory Errors
3.1 Error Types
- A: derefencing a non-pointer
- B: accessing a freed block
- C: freeing a freed block
- D: failing to free memory (memory leak)
- E: no bounds checking (potential buffer overflow)
- F: reading uninitialized memory
- G: referencing nonexistent variable
- H: wrong allocation size
3.2 Case 1
char s[8]; int i; gets(s); /* reads "123456789" from stdin */
Error Type | Program Stop Possible? | Fix |
---|---|---|
E, could overflow s |
yes | use fgets |
3.3 Case 2
int* foo() { int val = 0; return &val; }
Error Type | Program Stop Possible? | Fix |
---|---|---|
G, after foo returns, val will be deallocated |
no | pass a reference or use malloc |
3.4 Case 3
x = (int *) malloc( N * sizeof(int) ); // manipulate x free(x); ... y = (int *) malloc( M * sizeof(int) ); // manipulate y free(x);
Error Type | Program Stop Possible? | Fix |
---|---|---|
C, x freed twice |
yes | probably a typo, should be free(y) |
3.5 Case 4
N
andM
are defined elsewhere (#define
)
int **p; p = (int **) malloc( N * sizeof(int) ); for (int i = 0; i < N; i++) { p[i] = (int *) malloc( M * sizeof(int) ); }
Error Type | Program Stop Possible? | Fix |
---|---|---|
H, p points to an array of pointers, but malloc call allocates space for sizeof(int) |
yes | should be malloc( N * sizeof(int*) ) |
3.6 Case 5
A
is anN
×N
matrix,x
is anN
-sized vector (so the product is a vector of sizeN
N
is defined elsewhere (#define
)
/* return y = Ax */ int *matvec(int **A, int *x) { int *y = (int *) malloc( N * sizeof(int) ); int i, j; for (i = 0; i < N; i++) for (j = 0; j < N; j++) y[i] += A[i][j] * x[j]; return y; }
Error Type | Program Stop Possible? | Fix |
---|---|---|
F, using += with uninitialized elements of y |
no | use calloc(N, sizeof(int)) to allocate zero-initialized memory |
3.7 Case 6
scanf
signature:int scanf(const char *format, ...)
int val; ... scanf("%d", val);
Error Type | Program Stop Possible? | Fix |
---|---|---|
A, scanf takes the location where input will be stored, val treated as a pointer |
yes | should be scanf("%d", &val) |
3.8 Case 7
x = (int *) malloc( N * sizeof(int) ); // manipulate x free(x); ... y = (int *) malloc( M * sizeof(int) ); for (i = 0; i < M; i++) y[i] = x[i]++;
Error Type | Program Stop Possible? | Fix |
---|---|---|
B, x accessed after free(x) |
yes | free(x) should come later, after final access to x |
3.9 Case 8
typedef struct L { int val; struct L *next; } list; void foo() { list *head = (list *) malloc( sizeof(list) ); head->val = 0; head->next = NULL; // create and manipulate the rest of the list ... free(head); return; }
Error Type | Program Stop Possible? | Fix |
---|---|---|
D, nodes after head not freed and reference to them is lost |
no | iterate through the linked list to free each node |