Metaprogramovanie / Proces a jeho štruktúra

Sergej Chodarev

Proces a jeho štruktúra

Metaprogramovanie 3

Sergej Chodarev

Čo je to proces?

Proces

Vykonávanie inštrukcií

Pamäť

Linux process segment layout

Pamäť

Zásobník volaní

Halda vs zásobník

void foo() {
    int x = 5;
    int *p = malloc(sizeof(int));
    *p = 5;
}

Prečo zásobník?

Zásobník

Správa pamäte v halde

Stack overflow :(

Tail call optimization

Tail call

function foo(data) {
    ...
    return bar(data);
}

Klasický faktorial

(define (factorial n)
    (if (= n 1)
        1
        (* n (factorial (- n 1)))))
  

Structure and Interpretation of Computer Programs

Faktoriál s tail call

(define (factorial n)
    (define (iter product counter)
        (if (> counter n)
            product
            (iter (* counter product)
                  (+ counter 1))))
    (iter 1 1))

Java

Java

Reflexia

Reifikácia

Reifikácia (reification, zhmotnenie) – vytvorenie reprezentácie entity systému v meta-systéme.

Reifikácia

Ako reifikovať zásobník volaní?

Stack trace

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
      at Main.sayHello(Main.java:8)
      at Main.main(Main.java:4)

Starý spôsob

StackTraceElement

Príklad

Logger

public interface Logger {
  void logRecord(String className,
           String methodName,
           int lineNum,
           String message,
           int logRecordType);
  ...
}

Lepší Logger

public interface Logger {
    void logRecord(String message,
                   int logRecordType);
    ...
}

Implementácia

public void logRecord(String message, int logRecordType) {
    Throwable ex = new Throwable();
    StackTraceElement ste = ex.getStackTrace()[1];
    logRecord(ste.getClassName(), ste.getMethodName(),
            ste.getLineNumber(), message, logRecordType);
}

Java 9: StackWalker

public void logRecord(String message, int logRecordType) {
    StackWalker.getInstance()
        .walk(frames -> frames.skip(1).findFirst())
        .ifPresent(frame -> logRecord(
                frame.getClassName(),
                frame.getMethodName(),
                frame.getLineNumber(),
                message, logRecordType
        ));
}
StackWalker walker = StackWalker.getInstance(
                          Option.RETAIN_CLASS_REFERENCE);
Optional<Class<?>> callerClass = walker.walk(s ->
    s.map(StackFrame::getDeclaringClass)
        .filter(interestingClasses::contains)
        .findFirst());

Ďalšie informácie