Граф коммитов

1368 Коммитов

Автор SHA1 Сообщение Дата
nobu 5b3c9fc962 Get rid of unnecessary GCC extension
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58464 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-24 04:20:02 +00:00
nobu e601e77590 eval.c: copy special exceptions before raise
* eval.c (setup_exception): consider if the exception is frozen,
  but not one of special exception objects.

* gc.c (rb_memerror): copy minimum objects.

* thread.c (rb_threadptr_execute_interrupts): prepare special
  exception queued by another thread to be raised.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58380 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-17 02:31:35 +00:00
nobu 61d9da258d gc.c: rb_threadptr_stack_check
* gc.c (rb_threadptr_stack_check): check probability of stack
  overflow for the given thread, not the current thread.

* vm_eval.c (stack_check): check the given thread, not the current
  thread.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58375 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-17 00:10:47 +00:00
nobu b0d3649479 gc.c: PREVENT_STACK_OVERFLOW
* gc.c (PREVENT_STACK_OVERFLOW): define TRUE to try preventing
  stack overflow before actually happens.

* gc.c (stack_check): parameterize thread pointer.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58374 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-17 00:10:45 +00:00
nobu a1caed95cb thread.c: during GC for thread
* thread.c (ruby_thread_stack_overflow): check if the given thread
  is during GC.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58328 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-12 14:47:50 +00:00
nobu 79c50a77ff get rid of strcpy
* addr2line.c (follow_debuglink): insert global_debug_dir by using
  memmove instead of copying to temporary buffer.

* dln.c (dln_load): use memcpy with the known length instead of
  strcpy.

* gc.c (rb_gc_unprotect_logging): use strdup instead of malloc and
  strcpy.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-12-26 09:28:46 +00:00
ktsj 9cbd6ee097 * vm_trace.c (tracepoint_attr_callee_id, rb_tracearg_callee_id):
add TracePoint#callee_id. [ruby-core:77241] [Feature #12747]

* cont.c, eval.c, gc.c, include/ruby/intern.h, insns.def, thread.c,
  vm.c, vm_backtrace.c, vm_core.h, vm_eval.c, vm_insnhelper.c, vm_trace.c: ditto.

* test/ruby/test_settracefunc.rb: tests for above.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56593 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-11-05 13:15:27 +00:00
ko1 0b8ab5b0a8 * gc.c (heap_page_resurrect): do not return tomb_pages when
page->freelist == NULL.
  [Bug #12670]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56558 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-11-04 08:54:46 +00:00
nobu d94ea30a57 gc.c: fix GC_PROFILE_DETAIL_MEMORY
* gc.c (gc_prof_setup_new_record): fix the condition to get
  rusage.
* gc.c (gc_profile_dump_major_reason): remove undefined flags.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56373 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-10-07 11:21:41 +00:00
nobu 0cc169d1de fid typos [ci skip]
* fix typos, "a" before "Integer" to "an".  [Fix GH-1438]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56225 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-09-24 02:28:25 +00:00
kazu c6501cccb1 gc.c: fix rdoc of garbage_collect [ci skip]
* gc.c (gc_start_internal): [DOC] methods without arguments
  like r56194. [Bug #12777]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56201 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-09-22 04:06:53 +00:00
nobu 25049e983d gc.c: fix rdoc of garbage_collect [ci skip]
* gc.c (gc_start_internal): [DOC] add ObjectSpace.garbage_collect
  and fix GC#garbage_collect.  [Bug #12777]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56194 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-09-20 14:02:53 +00:00
nobu 68aa1d81cf gc.c: rb_gc_adjust_memory_usage
* gc.c (rb_gc_adjust_memory_usage): notify memory usage to the GC
  engine by extension libraries, to trigger GC.  [Feature #12690]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-09-20 07:52:25 +00:00
rhe 2f551849c4 Use PRIuSIZE format specifier for size_t values
Use PRIuSIZE instead of PRIdSIZE. This fixes the exception message shown
on too large xmalloc2. This commit also fixes other incorrect use of
PRIdSIZE in other functions; though most of them are debug print.

* gc.c (heap_extend_pages, get_envparam_size, ruby_malloc_size_overflow,
  gc_profile_dump_on): Use PRIuSIZE instead of PRIdSIZE as the passed
  value is size_t, not ssize_t.

* iseq.c (get_line_info, rb_iseq_disasm_insn): Ditto.

* sprintf.c (rb_str_format): Ditto.

* thread_win32.c (native_thread_create): Ditto.

* vm.c (get_param): Ditto.

* ext/objspace/objspace_dump.c (dump_append_string_content,
  dump_object): Ditto.

* ext/socket/raddrinfo.c (host_str, port_str): Ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56156 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-09-13 12:33:13 +00:00
akr 577de1e93d replace fixnum by integer in documents.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56102 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-09-08 04:57:49 +00:00
kou 8ddc191df4 * gc.c (gc_reset_malloc_info): Remove too much ";".
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56001 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-08-24 13:42:08 +00:00
ko1 e06698d257 * vm.c, internal.h: remove RubyVM::Env class and all of env objects
are imemo objects (imemo_env).

* NEWS: describe this change. I believe nobody touch these objects
  because there are no method defined.

* vm_core.h: remove the following definitions.
  * rb_cEnv decl.
  * GetEnvPtr() because Env is no longer T_DATA object.

* vm_core.h (rb_env_t): fix layout for imemo values.

* vm_core.h (vm_assert_env): added.

* vm_core.h (vm_env_new): added.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55768 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-07-28 19:13:26 +00:00
ko1 9f60791a04 * vm_core.h: revisit the structure of frame, block and env.
[Bug #12628]

  This patch introduce many changes.

  * Introduce concept of "Block Handler (BH)" to represent
    passed blocks.

  * move rb_control_frame_t::flag to ep[0] (as a special local
    variable). This flags represents not only frame type, but also
    env flags such as escaped.

  * rename `rb_block_t` to `struct rb_block`.

  * Make Proc, Binding and RubyVM::Env objects wb-protected.

  Check [Bug #12628] for more details.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55766 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-07-28 11:02:30 +00:00
nobu 3084f43047 gc.c: running finalizer state
* gc.c (run_finalizer): make saved running finalizer state
  volatile to ensure not to be clobbered by longjmp.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55759 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-07-26 13:43:38 +00:00
ko1 78e86f75ed * gc.c (rb_raw_obj_info): support to show Proc obj.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55754 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-07-26 10:07:12 +00:00
ko1 225915ef45 * gc.c (gc_mark): add `inline' explicitly.
I expected to inline this function implicitly at the loop
  (ex: marking T_ARRAY objects) but sometimes it remains as
  normal call.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55753 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-07-26 09:57:50 +00:00
nobu 2fbb1dca4e gc.c: reduce EXEC_TAG
* gc.c (run_finalizer): push and exec tag just once, instead of
  protecting for each finalizer.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55722 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-07-21 21:28:34 +00:00
nobu 2a32bd36ea gc.c: set finalizing
* gc.c (gc_start_internal, rb_gc_start): set finalizing flag
  whenever calling deferred finalizers not to recurse.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55720 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-07-21 21:12:53 +00:00
ko1 d7eb7bbcce * gc.c (gc_mark_roots): should mark the VM object itself to mark
singleton class of the VM object.
  Before this patch, we only set mark bit for the VM object and
  invoke mark function separately.
  [Bug #12583]

* test/ruby/test_gc.rb: add a test.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55663 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-07-13 07:08:32 +00:00
naruse b207e7cd1d include/ruby/defines.h (GCC_VERSION_SINCE): moved from internal.h
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54988 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-05-12 18:12:47 +00:00
naruse b3935f179b * gc.c (rb_gc_unprotect_logging): throw rb_memerror when it cannot
allocate memory. This is pointed out by Facebook's Infer.

* gc.c (gc_prof_setup_new_record): ditto.

* regparse.c (parse_regexp): ditto.

* util.c (MALLOC): use xmalloc and xfree like above.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54954 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-05-08 17:52:38 +00:00
naruse 28f5e12c24 * configure.in: check function attirbute const and pure,
and define CONSTFUNC and PUREFUNC if available.
  Note that I don't add those options as default because
  it still shows many false-positive (it seems not to consider
  longjmp).

* vm_eval.c (stack_check): get rb_thread_t* as an argument
  to avoid duplicate call of GET_THREAD().

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54952 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-05-08 17:44:51 +00:00
nobu 84f94652b0 use TH_JUMP_TAG
* vm_eval.c (rb_eval_cmd, rb_catch_obj): use TH_JUMP_TAG with the
  same rb_thread_t used for TH_PUSH_TAG, instead of JUMP_TAG with
  the current thread global variable.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54914 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-05-05 03:22:20 +00:00
naruse fac42e6c76 * include/ruby/ruby.h (rb_mul_size_overflow): added to handle
mul overflow efficiently.

* include/ruby/ruby.h (rb_alloc_tmp_buffer2): use rb_mul_size_overflow
  and avoid division where it can define DSIZE_T.

* gc.c (xmalloc2_size): moved from ruby.h and use rb_mul_size_overflow.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54704 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-04-22 11:42:31 +00:00
naruse 3738fe3333 * variable.c: use uint32_t instead of long to avoid confusion about
the type of ivtbl->numiv.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-04-22 09:47:34 +00:00
naruse feaa82a42b * gc.c (rb_alloc_tmp_buffer_with_count): added like xmalloc2 to
avoid duplicated check of size.

* gc.c (ruby_xmalloc2): added to keep separate layers.

* include/ruby/ruby.h (rb_alloc_tmp_buffer2): added to check
  the size more statically.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54664 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-04-21 20:59:40 +00:00
naruse fe120ac1f1 * gc.c (objspace_malloc_prepare): remove size check because it is
used by objspace_xmalloc and objspace_xcalloc.
  objspace_xmalloc introduces its own check in this commit.
  objspace_xcalloc checks with xmalloc2_size (ruby_xmalloc2_size).

* gc.c (objspace_xmalloc0): common xmalloc function.

* gc.c (objspace_xmalloc): introduce its own size check.

* gc.c (objspace_xmalloc2): separated from ruby_xmalloc2 to clarify
  the layer who has the responsibility to check the size.

* gc.c (objspace_xrealloc): remove duplicated size check.

* gc.c (ruby_xmalloc2): use objspace_xmalloc2.

* include/ruby/ruby.h (ruby_xmalloc2_size): follow the size limit
  as SSIZE_MAX. Note that ISO C says size_t is unsigned integer.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54661 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-04-21 20:59:39 +00:00
ko1 02f7507453 * gc.c: change deafult value of
RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO 0.3 -> 0.2
  RUBY_GC_HEAP_FREE_SLOTS_MAX_RATIO 0.8 -> 0.65

  These values are same as Ruby 2.0.0.

  This change cause GC counts.
  However, generational GC reduced each (minor) GC time and
  increase memory locality. So that not so big impact on my
  benchmarking results.
  (surprizingly, this fix speed up programs on some cases)

  You can change these values by environment variables
  if you feel wrong.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54482 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-04-04 08:49:17 +00:00
ko1 3287bad257 * gc.c (get_envparam_double): take an upper_bound.
And also take an accept_zero flag which allow to accept zero
  even if lower_bound is set.

* gc.c (ruby_gc_set_params): fix parameters.

  RUBY_GC_HEAP_FREE_SLOTS_MAX_RATIO set 0.9 as *lower_bound*, so that
  it should be upper_bound.
  Set RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO as lower bound.

  Also set lower/upper bound of RUBY_GC_HEAP_FREE_SLOTS_GOAL_RATIO to
  RUBY_GC_HEAP_FREE_SLOTS_MIN/MAX_RATIO.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54481 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-04-04 08:41:55 +00:00
nobu c55bcb9c43 gc.c: use PRIdSIZE
* gc.c (heap_extend_pages): fix format specifiers for size_t.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54455 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-31 12:46:15 +00:00
ko1 5951bbecb0 * gc.c: need to set initial value of GC_HEAP_FREE_SLOTS_GOAL_RATIO.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54454 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-31 10:16:48 +00:00
ko1 867693fe3d * gc.c: change additional allocation policy.
Introduce new environement variable
  GC_HEAP_FREE_SLOTS_GOAL_RATIO (goal_ratio) to calculate the ratio
  of additional memory.

  Before this change, we add pages with the following formula
  (when free_slots < total_pages * RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO):
    next_pages = total_pages * RUBY_GC_HEAP_GROWTH_FACTOR

  This addition can allocate too much.

  With this change, we increase pages to satisfy the following formula:
    next_free_slots = next_total_slots * goal_ratio
  where
    next_free_slots = free_slots + adding_slots
    next_total_slots = total_slots + adding_slots.

  If you want to prepare many free slots, increase this ratio.

  If this variable is 0, then simply multiply
  RUBY_GC_HEAP_GROWTH_FACTOR.

* gc.c (get_envparam_double): enable to accept 0.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54453 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-31 09:16:48 +00:00
ko1 9bb740d2ec * gc.c (gc_marks_finish): fix syntax error.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54452 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-31 08:49:09 +00:00
ko1 49369ef173 * gc.c: simplify allocate/free detecting logic at the end of marking.
Before this change, heap_pages_min_slots are calculated at the
  beggining sweeping phase. And this value is used at the end of
  *next* marking phase.

  To simplify it, we use this value at the end of this marking phase.
  It means that we don't need to store this value as global state.

  Also heap_pages_max_slots is calculated at the begging of sweeping
  phase and used at the end of sweeping phase.
  To simplify this logic, we introduced new global value
  heap_pages_freeable_pages it means extra pages count we can free.
  gc_sweep_step() checks this value and moves empty pages to tomb_heap
  not more than this value.

  Because of this fix, heap_pages_swept_slots is no longer needed.

* gc.c (rb_objspace_t::heap_pages): restruct the objspace global
  status.

  remove the following fileds
    * swept_slots (and heap_pages_swept_slots)
    * min_free_slots (and heap_pages_min_free_slots)
    * max_free_slots (and heap_pages_max_free_slots)
  And add the following filed.
    * freeable_pages (and heap_pages_freeable_pages)

* gc.c (heap_pages_free_unused_pages): unlink tomb heap pages
  because tomb heap should have only freeable pages.

* gc.c (heap_extend_pages): add parameters for future extension.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54451 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-31 08:21:35 +00:00
ko1 555f6cb089 * gc.c: add GC parameters to configure the following values:
* RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO:
    allocate additional pages when free slots is lower than
    the value (total_slots * (this ratio)).
  * RUBY_GC_HEAP_FREE_SLOTS_MAX_RATIO:
    allow to free pages when free slots is greater thatn
    the value (total_slots * (this ratio)).

  Before this change, these values are hard coded.

* gc.c (ruby_gc_params_t): ditto.

* gc.c (ruby_gc_set_params): ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54450 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-31 07:45:13 +00:00
svn fb296fe6fe * remove trailing spaces.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54449 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-31 07:02:41 +00:00
ko1 9a008c5865 * gc.c (gc_verify_heap_page): check the number of zombies.
* gc.c (gc_verify_heap_pages): check also tomb heap.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54448 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-31 07:02:40 +00:00
ko1 f46b5bcfaf * gc.c (gc_page_sweep): return free slots count.
* gc.c (gc_sweep_step): use returned free slots count.

* gc.c (gc_sweep_step): change variable name `next'
  to `next_sweep_page'.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54447 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-31 06:51:27 +00:00
nobu 764f39210b gc.c: fix r54115
* gc.c (gc_page_sweep): use the argument objspace.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54173 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-18 07:37:07 +00:00
nobu 7e81ca14fe gc.c: fix commit miss r54145
* gc.c (tick): fix missing close parenthesis.  [Fix GH-1291]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54170 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-18 03:25:32 +00:00
nobu a5456a1d83 gc.c: tick for POWER arch
* gc.c (tick): Use __builtin_ppc_get_timebase for POWER arch.
  [Fix GH-1291]

This gives a little performance improvement

        user     system      total        real
Before: 20.870000   0.000000  20.870000 ( 20.893959)
After:  20.720000   0.000000  20.720000 ( 20.733970)

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54145 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-17 08:14:53 +00:00
nobu ed921b85dc gc.c: mark_stack_locations
* gc.c (mark_stack_locations): extract the common part from
  mark_current_machine_context and rb_gc_mark_machine_stack.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54116 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-15 07:02:09 +00:00
nobu d424873980 gc.c: rb_objspace_of
* gc.c (rb_objspace_of): macro to get the objspace from a thread.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54115 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-15 06:42:29 +00:00
nobu cbfe564ed2 gc.c: expand a local macro
* gc.c (mark_current_machine_context, rb_gc_mark_machine_stack):
  expand rb_gc_mark_locations local macro.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54114 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-15 06:42:27 +00:00
ko1 d04ee29e77 * gc.c: use 2 bits with unsigned int for rb_objspace:🎏:mode
because it always returns 0 to 2 (non-negative value).


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53997 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-04 10:37:35 +00:00