Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Izhevsk PHP Meetup #3. Вместо keynote

Izhevsk PHP Meetup #3. Вместо keynote

Святослав Молодских, ресурс-менеджер, Центр Высоких Технологий
Это будет почти технический доклад с привкусом языка C и структур.

Izhevsk PHP Meetup

September 28, 2017
Tweet

More Decks by Izhevsk PHP Meetup

Other Decks in Technology

Transcript

  1. Новый доклад (1)

    View Slide

  2. Кто я?
    • Святослав Молодских
    • Работаю 8 лет в одной компании, большую часть
    времени программистом
    • Перешёл на тёмную сторону

    View Slide

  3. View Slide

  4. View Slide

  5. Структура
    struct point {
    int x;
    int y;
    };

    View Slide

  6. Указатель

    View Slide

  7. Объединение
    union Data {
    int i;
    float f;
    char str[20];
    };

    View Slide

  8. Контейнеры

    View Slide

  9. zval
    // zend_types.h
    typedef struct _zval_struct zval;
    // zend.h
    struct _zval_struct {
    /* Variable information */
    zvalue_value value; /* value */
    zend_uint refcount__gc;
    zend_uchar type;/* active type */
    zend_uchar is_ref__gc;
    };

    View Slide

  10. zvalue_value
    // zend.h
    typedef union _zvalue_value {
    long lval; /* long value */
    double dval; /* double value */
    struct {
    char *val;
    int len;
    } str;
    HashTable *ht; /* hash table value */
    zend_object_value obj;
    zend_ast *ast;
    } zvalue_value;

    View Slide

  11. Снова zval
    // zend.h
    struct _zval_struct {
    /* Variable information */
    zvalue_value value; /* value */
    zend_uint refcount__gc;
    zend_uchar type;/* active type */
    zend_uchar is_ref__gc;
    };

    View Slide

  12. "foo": {
    "type": "string",
    "value": {
    "str": {
    "val": "foo",
    "len": 3
    }
    },
    "refcount": 1,
    "is_ref": 0
    }
    $foo = 'foo';

    View Slide

  13. "foo", "bar": {
    "type": "string",
    "value": {
    "str": {
    "val": "foo",
    "len": 3
    }
    },
    "refcount": 2,
    "is_ref": 0
    }
    $foo = ‘foo';
    $bar = $foo;

    View Slide

  14. "bar": {
    "type": "string",
    "value": {
    "str": {
    "val": "foo",
    "len": 3
    }
    },
    "refcount": 1,
    "is_ref": 0
    }
    $foo = 'foo';
    $bar = $foo;
    unset($foo);

    View Slide

  15. foo.value.refcount --
    if refcount == 0
    del(value)
    unset($foo);

    View Slide

  16. $foo = 'foo';
    $bar = $foo;
    $bar .= 'bar';
    "foo": {
    "type": "string",
    "value": {
    "str": {
    "val": "foo",
    "len": 3
    }
    },
    "refcount": 1,
    "is_ref": 0
    },
    "bar": {
    "type": "string",
    "value": {
    "str": {
    "val": "foobar",
    "len": 6
    }
    },
    "refcount": 1,
    "is_ref": 0
    }

    View Slide

  17. COW

    View Slide

  18. Copy-on-write

    View Slide

  19. $foo = 'foo';
    $bar = $foo;
    $baz = &$foo;
    "baz", "foo": {
    "type": "string",
    "value": {
    "str": {
    "val": "foo",
    "len": 3
    }
    },
    "refcount": 2,
    "is_ref": 1
    },
    "bar": {
    "type": "string",
    "value": {
    "str": {
    "val": "foo",
    "len": 3
    }
    },
    "refcount": 1,
    "is_ref": 0
    }

    View Slide

  20. $foo = 'foo';
    $bar = $foo;
    $baz = &$foo;
    $spam = $foo;
    "baz", "foo": {
    "type": "string",
    "value": {
    "str": {
    "val": "foo",
    "len": 3
    }
    },
    "refcount": 2,
    "is_ref": 1
    },
    "bar": {
    "type": "string",
    "value": {
    "str": {
    "val": "foo",
    "len": 3
    }
    },
    "refcount": 1,
    "is_ref": 0
    },
    "spam": {
    "type": "string",
    "value": {
    "str": {
    "val": "foo",
    "len": 3
    }
    },
    "refcount": 1,
    "is_ref": 0
    }

    View Slide

  21. Медленно
    $foo = [1];
    $bar = &$foo;
    count($bar);

    View Slide

  22. PHP 7
    /* regular data types */
    #define IS_UNDEF 0
    #define IS_NULL 1
    #define IS_FALSE 2
    #define IS_TRUE 3
    #define IS_LONG 4
    #define IS_DOUBLE 5
    #define IS_STRING 6
    #define IS_ARRAY 7
    #define IS_OBJECT 8
    #define IS_RESOURCE 9
    #define IS_REFERENCE 10
    /* constant expressions */
    #define IS_CONSTANT 11
    #define IS_CONSTANT_AST 12

    View Slide

  23. zval
    struct _zval_struct {
    zend_value value; /* value */
    union {
    struct {
    ZEND_ENDIAN_LOHI_4(
    zend_uchar type, /* active type */
    zend_uchar type_flags,
    zend_uchar const_flags,
    zend_uchar reserved) /* call info for EX(This) */
    } v;
    uint32_t type_info;
    } u1;
    union {
    uint32_t var_flags;
    uint32_t next; /* hash collision chain */
    uint32_t cache_slot; /* literal cache slot */
    uint32_t lineno; /* line number (for ast nodes) */
    uint32_t num_args; /* arguments number for EX(This) */
    uint32_t fe_pos; /* foreach position */
    uint32_t fe_iter_idx; /* foreach iterator index */
    } u2;
    };

    View Slide

  24. zend_value
    typedef union _zend_value {
    zend_long lval; /* long value */
    double dval; /* double value */
    zend_refcounted *counted;
    zend_string *str;
    zend_array *arr;
    zend_object *obj;
    zend_resource *res;
    zend_reference *ref;
    zend_ast_ref *ast;
    zval *zv;
    void *ptr;
    zend_class_entry *ce;
    zend_function *func;
    struct {
    uint32_t w1;
    uint32_t w2;
    } ww;
    } zend_value;

    View Slide

  25. zend_refcounted
    typedef struct _zend_refcounted zend_refcounted;
    struct _zend_refcounted {
    zend_refcounted_h gc;
    };
    typedef struct _zend_refcounted_h {
    uint32_t refcount; /* reference counter 32-bit */
    union {
    struct {
    ZEND_ENDIAN_LOHI_3(
    zend_uchar type,
    zend_uchar flags, /* used for strings & objects */
    uint16_t gc_info) /* keeps GC root number (or 0) and color */
    } v;
    uint32_t type_info;
    } u;
    } zend_refcounted_h;

    View Slide

  26. zend_reference
    typedef struct _zend_reference zend_reference;
    struct _zend_reference {
    zend_refcounted_h gc;
    zval val;
    };

    View Slide

  27. $foo
    $foo = []; zend_array_1(refcount=1, val=[])
    $bar = $foo; $foo, $bar zend_array_1(refcount=2, val=[])
    $baz = $bar; $foo, $bar, $baz zend_array_1(refcount=3, val=[])
    $spam = &$baz; $foo, $bar zend_array_1(refcount=3, val=[])
    $baz, $spam zend_reference_1(refcount=2)
    $spam[] = 1; $foo, $bar zend_array_1(refcount=2, val=[])
    $baz, $spam zend_reference_1(refcount=2)
    zend_array_1(refcount=1, val=[1])

    View Slide

  28. Вопросы?

    View Slide