Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge commit '796a9f113cd71cadf70741130daddf106945fae9' into hj-dev-p…

…alfia
  • Loading branch information...
commit a4f06936957b299381fead9790acfc435a448306 2 parents ba470ac + 796a9f1
Akos Palfi authored
Showing with 855 additions and 4,606 deletions.
  1. +0 −4 Makefile
  2. +0 −24 SConstruct
  3. +0 −9 build/common.gypi
  4. +45 −14 include/v8.h
  5. +0 −2  src/SConscript
  6. +6 −32 src/api.cc
  7. +11 −18 src/arm/code-stubs-arm.cc
  8. +15 −4 src/arm/codegen-arm.cc
  9. +12 −12 src/arm/full-codegen-arm.cc
  10. +14 −5 src/arm/ic-arm.cc
  11. +31 −9 src/arm/lithium-codegen-arm.cc
  12. +2 −1  src/arm/lithium-codegen-arm.h
  13. +6 −2 src/arm/stub-cache-arm.cc
  14. +9 −9 src/builtins.h
  15. +5 −4 src/code-stubs.cc
  16. +16 −5 src/code-stubs.h
  17. +11 −3 src/codegen.h
  18. +0 −6 src/d8.cc
  19. +0 −617 src/d8.js
  20. +0 −123 src/debug-debugger.js
  21. +2 −6 src/flag-definitions.h
  22. +8 −1 src/global-handles.cc
  23. +4 −0 src/heap-inl.h
  24. +32 −10 src/heap.cc
  25. +5 −3 src/heap.h
  26. +7 −0 src/hydrogen-instructions.cc
  27. +19 −7 src/hydrogen-instructions.h
  28. +20 −5 src/hydrogen.cc
  29. +11 −18 src/ia32/code-stubs-ia32.cc
  30. +15 −4 src/ia32/codegen-ia32.cc
  31. +10 −1 src/ia32/deoptimizer-ia32.cc
  32. +10 −11 src/ia32/full-codegen-ia32.cc
  33. +14 −5 src/ia32/ic-ia32.cc
  34. +31 −9 src/ia32/lithium-codegen-ia32.cc
  35. +2 −1  src/ia32/lithium-codegen-ia32.h
  36. +6 −2 src/ia32/stub-cache-ia32.cc
  37. +20 −3 src/ic.cc
  38. +0 −11 src/ic.h
  39. +0 −63 src/inspector.cc
  40. +5 −1 src/isolate.cc
  41. +2 −16 src/jsregexp.cc
  42. +0 −126 src/liveobjectlist-inl.h
  43. +0 −2,631 src/liveobjectlist.cc
  44. +0 −319 src/liveobjectlist.h
  45. +0 −5 src/mark-compact.cc
  46. +5 −0 src/objects-inl.h
  47. +1 −1  src/objects-visiting-inl.h
  48. +57 −9 src/objects.cc
  49. +8 −4 src/objects.h
  50. +5 −4 src/platform-linux.cc
  51. +5 −202 src/runtime.cc
  52. +0 −14 src/runtime.h
  53. +0 −1  src/spaces.cc
  54. +1 −1  src/type-info.cc
  55. +30 −0 src/unicode-inl.h
  56. +1 −0  src/unicode.h
  57. +2 −0  src/v8globals.h
  58. +0 −93 src/v8utils.cc
  59. +2 −32 src/v8utils.h
  60. +10 −18 src/x64/code-stubs-x64.cc
  61. +15 −4 src/x64/codegen-x64.cc
  62. +10 −11 src/x64/full-codegen-x64.cc
  63. +14 −5 src/x64/ic-x64.cc
  64. +30 −9 src/x64/lithium-codegen-x64.cc
  65. +2 −1  src/x64/lithium-codegen-x64.h
  66. +6 −2 src/x64/stub-cache-x64.cc
  67. +34 −0 test/cctest/test-api.cc
  68. +37 −0 test/cctest/test-strings.cc
  69. +114 −0 test/mjsunit/allocation-site-info.js
  70. +19 −29 src/inspector.h → test/mjsunit/regress/regress-2489.js
  71. +41 −5 tools/gyp/v8.gyp
View
4 Makefile
@@ -83,10 +83,6 @@ endif
ifeq ($(gdbjit), on)
GYPFLAGS += -Dv8_enable_gdbjit=1
endif
-# liveobjectlist=on
-ifeq ($(liveobjectlist), on)
- GYPFLAGS += -Dv8_use_liveobjectlist=true
-endif
# vfp2=off
ifeq ($(vfp2), off)
GYPFLAGS += -Dv8_can_use_vfp2_instructions=false
View
24 SConstruct
@@ -67,16 +67,9 @@ LIBRARY_FLAGS = {
'debuggersupport:on': {
'CPPDEFINES': ['ENABLE_DEBUGGER_SUPPORT'],
},
- 'inspector:on': {
- 'CPPDEFINES': ['INSPECTOR'],
- },
'fasttls:off': {
'CPPDEFINES': ['V8_NO_FAST_TLS'],
},
- 'liveobjectlist:on': {
- 'CPPDEFINES': ['ENABLE_DEBUGGER_SUPPORT', 'INSPECTOR',
- 'LIVE_OBJECT_LIST', 'OBJECT_PRINT'],
- }
},
'gcc': {
'all': {
@@ -1051,16 +1044,6 @@ SIMPLE_OPTIONS = {
'default': 'on',
'help': 'enable debugging of JavaScript code'
},
- 'inspector': {
- 'values': ['on', 'off'],
- 'default': 'off',
- 'help': 'enable inspector features'
- },
- 'liveobjectlist': {
- 'values': ['on', 'off'],
- 'default': 'off',
- 'help': 'enable live object list features in the debugger'
- },
'soname': {
'values': ['on', 'off'],
'default': 'off',
@@ -1418,13 +1401,6 @@ def PostprocessOptions(options, os):
options['msvcltcg'] = 'on'
if (options['mipsabi'] != 'none') and (options['arch'] != 'mips') and (options['simulator'] != 'mips'):
options['mipsabi'] = 'none'
- if options['liveobjectlist'] == 'on':
- if (options['debuggersupport'] != 'on') or (options['mode'] == 'release'):
- # Print a warning that liveobjectlist will implicitly enable the debugger
- print "Warning: forcing debuggersupport on for liveobjectlist"
- options['debuggersupport'] = 'on'
- options['inspector'] = 'on'
- options['objectprint'] = 'on'
def ParseEnvOverrides(arg, imports):
View
9 build/common.gypi
@@ -92,7 +92,6 @@
'v8_use_snapshot%': 'true',
'host_os%': '<(OS)',
- 'v8_use_liveobjectlist%': 'false',
'werror%': '-Werror',
# With post mortem support enabled, metadata is embedded into libv8 that
@@ -257,14 +256,6 @@
},
'msvs_configuration_platform': 'x64',
}], # v8_target_arch=="x64"
- ['v8_use_liveobjectlist=="true"', {
- 'defines': [
- 'ENABLE_DEBUGGER_SUPPORT',
- 'INSPECTOR',
- 'OBJECT_PRINT',
- 'LIVEOBJECTLIST',
- ],
- }],
['v8_compress_startup_data=="bz2"', {
'defines': [
'COMPRESS_STARTUP_DATA_BZ2',
View
59 include/v8.h
@@ -1135,9 +1135,9 @@ class V8EXPORT String : public Primitive {
int options = NO_OPTIONS) const;
// One byte characters.
int WriteOneByte(uint8_t* buffer,
- int start = 0,
- int length = -1,
- int options = NO_OPTIONS) const;
+ int start = 0,
+ int length = -1,
+ int options = NO_OPTIONS) const;
// UTF-8 encoded characters.
int WriteUtf8(char* buffer,
int length = -1,
@@ -3541,9 +3541,6 @@ class V8EXPORT V8 {
static bool IsGlobalWeak(internal::Object** global_handle);
static bool IsGlobalWeak(internal::Isolate* isolate,
internal::Object** global_handle);
- static void SetWrapperClassId(internal::Object** global_handle,
- uint16_t class_id);
- static uint16_t GetWrapperClassId(internal::Object** global_handle);
template <class T> friend class Handle;
template <class T> friend class Local;
@@ -3796,6 +3793,9 @@ class V8EXPORT Context {
/** Returns true if V8 has a current context. */
static bool InContext();
+ /** Returns an isolate associated with a current context. */
+ v8::Isolate* GetIsolate();
+
/**
* Gets the embedder data with the given index, which must have been set by a
* previous call to SetEmbedderData with the same index. Note that index 0
@@ -4152,12 +4152,17 @@ class Internals {
static const int kIsolateStateOffset = 0;
static const int kIsolateEmbedderDataOffset = 1 * kApiPointerSize;
static const int kIsolateRootsOffset = 3 * kApiPointerSize;
+ static const int kNodeClassIdOffset = 1 * kApiPointerSize;
+ static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3;
static const int kUndefinedValueRootIndex = 5;
static const int kNullValueRootIndex = 7;
static const int kTrueValueRootIndex = 8;
static const int kFalseValueRootIndex = 9;
static const int kEmptySymbolRootIndex = 119;
+ static const int kNodeIsIndependentShift = 4;
+ static const int kNodeIsPartiallyDependentShift = 5;
+
static const int kJSObjectType = 0xab;
static const int kFirstNonstringType = 0x80;
static const int kOddballType = 0x82;
@@ -4196,6 +4201,18 @@ class Internals {
return *reinterpret_cast<int*>(addr) == 1;
}
+ V8_INLINE(static uint8_t GetNodeFlag(internal::Object** obj, int shift)) {
+ uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
+ return *addr & (1 << shift);
+ }
+
+ V8_INLINE(static void UpdateNodeFlag(internal::Object** obj,
+ bool value, int shift)) {
+ uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
+ uint8_t mask = 1 << shift;
+ *addr = (*addr & ~mask) | (value << shift);
+ }
+
V8_INLINE(static void SetEmbedderData(v8::Isolate* isolate, void* data)) {
uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) +
kIsolateEmbedderDataOffset;
@@ -4289,9 +4306,11 @@ bool Persistent<T>::IsIndependent() const {
template <class T>
bool Persistent<T>::IsIndependent(Isolate* isolate) const {
+ typedef internal::Internals I;
if (this->IsEmpty()) return false;
- return V8::IsGlobalIndependent(reinterpret_cast<internal::Isolate*>(isolate),
- reinterpret_cast<internal::Object**>(**this));
+ if (!I::IsInitialized(isolate)) return false;
+ return I::GetNodeFlag(reinterpret_cast<internal::Object**>(**this),
+ I::kNodeIsIndependentShift);
}
@@ -4363,8 +4382,11 @@ void Persistent<T>::MarkIndependent() {
template <class T>
void Persistent<T>::MarkIndependent(Isolate* isolate) {
- V8::MarkIndependent(reinterpret_cast<internal::Isolate*>(isolate),
- reinterpret_cast<internal::Object**>(**this));
+ typedef internal::Internals I;
+ if (this->IsEmpty()) return;
+ if (!I::IsInitialized(isolate)) return;
+ I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(**this),
+ true, I::kNodeIsIndependentShift);
}
template <class T>
@@ -4374,18 +4396,27 @@ void Persistent<T>::MarkPartiallyDependent() {
template <class T>
void Persistent<T>::MarkPartiallyDependent(Isolate* isolate) {
- V8::MarkPartiallyDependent(reinterpret_cast<internal::Isolate*>(isolate),
- reinterpret_cast<internal::Object**>(**this));
+ typedef internal::Internals I;
+ if (this->IsEmpty()) return;
+ if (!I::IsInitialized(isolate)) return;
+ I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(**this),
+ true, I::kNodeIsPartiallyDependentShift);
}
template <class T>
void Persistent<T>::SetWrapperClassId(uint16_t class_id) {
- V8::SetWrapperClassId(reinterpret_cast<internal::Object**>(**this), class_id);
+ typedef internal::Internals I;
+ internal::Object** obj = reinterpret_cast<internal::Object**>(**this);
+ uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
+ *reinterpret_cast<uint16_t*>(addr) = class_id;
}
template <class T>
uint16_t Persistent<T>::WrapperClassId() const {
- return V8::GetWrapperClassId(reinterpret_cast<internal::Object**>(**this));
+ typedef internal::Internals I;
+ internal::Object** obj = reinterpret_cast<internal::Object**>(**this);
+ uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
+ return *reinterpret_cast<uint16_t*>(addr);
}
Arguments::Arguments(internal::Object** implicit_args,
View
2  src/SConscript
@@ -89,7 +89,6 @@ SOURCES = {
hydrogen.cc
ic.cc
incremental-marking.cc
- inspector.cc
interface.cc
interpreter-irregexp.cc
isolate.cc
@@ -97,7 +96,6 @@ SOURCES = {
lithium-allocator.cc
lithium.cc
liveedit.cc
- liveobjectlist.cc
log-utils.cc
log.cc
mark-compact.cc
View
38 src/api.cc
@@ -668,13 +668,6 @@ void V8::MarkIndependent(i::Object** object) {
}
-void V8::MarkIndependent(i::Isolate* isolate, i::Object** object) {
- ASSERT(isolate == i::Isolate::Current());
- LOG_API(isolate, "MarkIndependent");
- isolate->global_handles()->MarkIndependent(object);
-}
-
-
void V8::MarkPartiallyDependent(i::Object** object) {
i::Isolate* isolate = i::Isolate::Current();
LOG_API(isolate, "MarkPartiallyDependent");
@@ -682,13 +675,6 @@ void V8::MarkPartiallyDependent(i::Object** object) {
}
-void V8::MarkPartiallyDependent(i::Isolate* isolate, i::Object** object) {
- ASSERT(isolate == i::Isolate::Current());
- LOG_API(isolate, "MarkPartiallyDependent");
- isolate->global_handles()->MarkPartiallyDependent(object);
-}
-
-
bool V8::IsGlobalIndependent(i::Object** obj) {
i::Isolate* isolate = i::Isolate::Current();
LOG_API(isolate, "IsGlobalIndependent");
@@ -697,14 +683,6 @@ bool V8::IsGlobalIndependent(i::Object** obj) {
}
-bool V8::IsGlobalIndependent(i::Isolate* isolate, i::Object** obj) {
- ASSERT(isolate == i::Isolate::Current());
- LOG_API(isolate, "IsGlobalIndependent");
- if (!isolate->IsInitialized()) return false;
- return i::GlobalHandles::IsIndependent(obj);
-}
-
-
bool V8::IsGlobalNearDeath(i::Object** obj) {
i::Isolate* isolate = i::Isolate::Current();
LOG_API(isolate, "IsGlobalNearDeath");
@@ -4704,6 +4682,12 @@ bool Context::InContext() {
}
+v8::Isolate* Context::GetIsolate() {
+ i::Handle<i::Context> env = Utils::OpenHandle(this);
+ return reinterpret_cast<Isolate*>(env->GetIsolate());
+}
+
+
v8::Local<v8::Context> Context::GetEntered() {
i::Isolate* isolate = i::Isolate::Current();
if (!EnsureInitializedForIsolate(isolate, "v8::Context::GetEntered()")) {
@@ -4823,16 +4807,6 @@ void Context::SetErrorMessageForCodeGenerationFromStrings(
}
-void V8::SetWrapperClassId(i::Object** global_handle, uint16_t class_id) {
- i::GlobalHandles::SetWrapperClassId(global_handle, class_id);
-}
-
-
-uint16_t V8::GetWrapperClassId(internal::Object** global_handle) {
- return i::GlobalHandles::GetWrapperClassId(global_handle);
-}
-
-
Local<v8::Object> ObjectTemplate::NewInstance() {
i::Isolate* isolate = i::Isolate::Current();
ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
View
29 src/arm/code-stubs-arm.cc
@@ -344,7 +344,7 @@ static void GenerateFastCloneShallowArrayCommon(
MacroAssembler* masm,
int length,
FastCloneShallowArrayStub::Mode mode,
- AllocationSiteInfoMode allocation_site_info_mode,
+ AllocationSiteMode allocation_site_mode,
Label* fail) {
// Registers on entry:
//
@@ -358,9 +358,10 @@ static void GenerateFastCloneShallowArrayCommon(
? FixedDoubleArray::SizeFor(length)
: FixedArray::SizeFor(length);
}
+
int size = JSArray::kSize;
int allocation_info_start = size;
- if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+ if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
size += AllocationSiteInfo::kSize;
}
size += elements_size;
@@ -373,7 +374,7 @@ static void GenerateFastCloneShallowArrayCommon(
}
__ AllocateInNewSpace(size, r0, r1, r2, fail, flags);
- if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+ if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
__ mov(r2, Operand(Handle<Map>(masm->isolate()->heap()->
allocation_site_info_map())));
__ str(r2, FieldMemOperand(r0, allocation_info_start));
@@ -392,7 +393,7 @@ static void GenerateFastCloneShallowArrayCommon(
// Get hold of the elements array of the boilerplate and setup the
// elements pointer in the resulting object.
__ ldr(r3, FieldMemOperand(r3, JSArray::kElementsOffset));
- if (allocation_site_info_mode == TRACK_ALLOCATION_SITE_INFO) {
+ if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
__ add(r2, r0, Operand(JSArray::kSize + AllocationSiteInfo::kSize));
} else {
__ add(r2, r0, Operand(JSArray::kSize));
@@ -423,22 +424,14 @@ void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
__ b(eq, &slow_case);
FastCloneShallowArrayStub::Mode mode = mode_;
- AllocationSiteInfoMode allocation_site_info_mode =
- DONT_TRACK_ALLOCATION_SITE_INFO;
- if (mode == CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO) {
- mode = CLONE_ANY_ELEMENTS;
- allocation_site_info_mode = TRACK_ALLOCATION_SITE_INFO;
- }
-
if (mode == CLONE_ANY_ELEMENTS) {
Label double_elements, check_fast_elements;
__ ldr(r0, FieldMemOperand(r3, JSArray::kElementsOffset));
__ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
__ CompareRoot(r0, Heap::kFixedCOWArrayMapRootIndex);
__ b(ne, &check_fast_elements);
- GenerateFastCloneShallowArrayCommon(masm, 0,
- COPY_ON_WRITE_ELEMENTS,
- allocation_site_info_mode,
+ GenerateFastCloneShallowArrayCommon(masm, 0, COPY_ON_WRITE_ELEMENTS,
+ allocation_site_mode_,
&slow_case);
// Return and remove the on-stack parameters.
__ add(sp, sp, Operand(3 * kPointerSize));
@@ -447,9 +440,8 @@ void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
__ bind(&check_fast_elements);
__ CompareRoot(r0, Heap::kFixedArrayMapRootIndex);
__ b(ne, &double_elements);
- GenerateFastCloneShallowArrayCommon(masm, length_,
- CLONE_ELEMENTS,
- allocation_site_info_mode,
+ GenerateFastCloneShallowArrayCommon(masm, length_, CLONE_ELEMENTS,
+ allocation_site_mode_,
&slow_case);
// Return and remove the on-stack parameters.
__ add(sp, sp, Operand(3 * kPointerSize));
@@ -483,7 +475,8 @@ void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
}
GenerateFastCloneShallowArrayCommon(masm, length_, mode,
- allocation_site_info_mode, &slow_case);
+ allocation_site_mode_,
+ &slow_case);
// Return and remove the on-stack parameters.
__ add(sp, sp, Operand(3 * kPointerSize));
View
19 src/arm/codegen-arm.cc
@@ -144,7 +144,8 @@ void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const {
#define __ ACCESS_MASM(masm)
void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
- MacroAssembler* masm) {
+ MacroAssembler* masm, AllocationSiteMode mode,
+ Label* allocation_site_info_found) {
// ----------- S t a t e -------------
// -- r0 : value
// -- r1 : key
@@ -153,6 +154,12 @@ void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
// -- r3 : target map, scratch for subsequent call
// -- r4 : scratch (elements)
// -----------------------------------
+ if (mode == TRACK_ALLOCATION_SITE) {
+ ASSERT(allocation_site_info_found != NULL);
+ masm->TestJSArrayForAllocationSiteInfo(r2, r4,
+ allocation_site_info_found);
+ }
+
// Set transitioned map.
__ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset));
__ RecordWriteField(r2,
@@ -167,7 +174,7 @@ void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
void ElementsTransitionGenerator::GenerateSmiToDouble(
- MacroAssembler* masm, Label* fail) {
+ MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
// ----------- S t a t e -------------
// -- r0 : value
// -- r1 : key
@@ -179,7 +186,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
Label loop, entry, convert_hole, gc_required, only_change_map, done;
bool vfp2_supported = CpuFeatures::IsSupported(VFP2);
- if (FLAG_track_allocation_sites) {
+ if (mode == TRACK_ALLOCATION_SITE) {
masm->TestJSArrayForAllocationSiteInfo(r2, r4, fail);
}
@@ -308,7 +315,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
void ElementsTransitionGenerator::GenerateDoubleToObject(
- MacroAssembler* masm, Label* fail) {
+ MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
// ----------- S t a t e -------------
// -- r0 : value
// -- r1 : key
@@ -319,6 +326,10 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
// -----------------------------------
Label entry, loop, convert_hole, gc_required, only_change_map;
+ if (mode == TRACK_ALLOCATION_SITE) {
+ masm->TestJSArrayForAllocationSiteInfo(r2, r4, fail);
+ }
+
// Check for empty arrays, which only require a map transition and no changes
// to the backing store.
__ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset));
View
24 src/arm/full-codegen-arm.cc
@@ -1719,7 +1719,9 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
if (has_fast_elements && constant_elements_values->map() ==
isolate()->heap()->fixed_cow_array_map()) {
FastCloneShallowArrayStub stub(
- FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
+ FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
+ DONT_TRACK_ALLOCATION_SITE,
+ length);
__ CallStub(&stub);
__ IncrementCounter(
isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2);
@@ -1730,19 +1732,17 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
} else {
ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
FLAG_smi_only_arrays);
- FastCloneShallowArrayStub::Mode mode = has_fast_elements
- ? FastCloneShallowArrayStub::CLONE_ELEMENTS
- : FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
-
- // Tracking allocation info allows us to pre-transition later if it makes
- // sense.
- if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS &&
- FLAG_track_allocation_sites) {
- mode = FastCloneShallowArrayStub::
- CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO;
+ FastCloneShallowArrayStub::Mode mode =
+ FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
+ AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites
+ ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE;
+
+ if (has_fast_elements) {
+ mode = FastCloneShallowArrayStub::CLONE_ELEMENTS;
+ allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
}
- FastCloneShallowArrayStub stub(mode, length);
+ FastCloneShallowArrayStub stub(mode, allocation_site_mode, length);
__ CallStub(&stub);
}
View
19 src/arm/ic-arm.cc
@@ -1249,7 +1249,9 @@ void KeyedStoreIC::GenerateTransitionElementsSmiToDouble(MacroAssembler* masm) {
// Must return the modified receiver in r0.
if (!FLAG_trace_elements_transitions) {
Label fail;
- ElementsTransitionGenerator::GenerateSmiToDouble(masm, &fail);
+ AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS,
+ FAST_DOUBLE_ELEMENTS);
+ ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, &fail);
__ mov(r0, r2);
__ Ret();
__ bind(&fail);
@@ -1270,7 +1272,9 @@ void KeyedStoreIC::GenerateTransitionElementsDoubleToObject(
// Must return the modified receiver in r0.
if (!FLAG_trace_elements_transitions) {
Label fail;
- ElementsTransitionGenerator::GenerateDoubleToObject(masm, &fail);
+ AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_DOUBLE_ELEMENTS,
+ FAST_ELEMENTS);
+ ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, &fail);
__ mov(r0, r2);
__ Ret();
__ bind(&fail);
@@ -1406,7 +1410,9 @@ static void KeyedStoreGenerateGenericHelper(
r4,
slow);
ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
- ElementsTransitionGenerator::GenerateSmiToDouble(masm, slow);
+ AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS,
+ FAST_DOUBLE_ELEMENTS);
+ ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, slow);
__ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
__ jmp(&fast_double_without_map_check);
@@ -1418,7 +1424,9 @@ static void KeyedStoreGenerateGenericHelper(
r4,
slow);
ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
+ mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
+ ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm, mode,
+ slow);
__ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
__ jmp(&finish_object_store);
@@ -1432,7 +1440,8 @@ static void KeyedStoreGenerateGenericHelper(
r4,
slow);
ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
- ElementsTransitionGenerator::GenerateDoubleToObject(masm, slow);
+ mode = AllocationSiteInfo::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
+ ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, slow);
__ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
__ jmp(&finish_object_store);
}
View
40 src/arm/lithium-codegen-arm.cc
@@ -5431,6 +5431,8 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
Handle<FixedArray> literals(instr->environment()->closure()->literals());
ElementsKind boilerplate_elements_kind =
instr->hydrogen()->boilerplate_elements_kind();
+ AllocationSiteMode allocation_site_mode =
+ instr->hydrogen()->allocation_site_mode();
// Deopt if the array literal boilerplate ElementsKind is of a type different
// than the expected one. The check isn't necessary if the boilerplate has
@@ -5462,7 +5464,7 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
ASSERT(instr->hydrogen()->depth() == 1);
FastCloneShallowArrayStub::Mode mode =
FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS;
- FastCloneShallowArrayStub stub(mode, length);
+ FastCloneShallowArrayStub stub(mode, DONT_TRACK_ALLOCATION_SITE, length);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
} else if (instr->hydrogen()->depth() > 1) {
CallRuntime(Runtime::kCreateArrayLiteral, 3, instr);
@@ -5471,9 +5473,9 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
} else {
FastCloneShallowArrayStub::Mode mode =
boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS
- ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS
- : FastCloneShallowArrayStub::CLONE_ELEMENTS;
- FastCloneShallowArrayStub stub(mode, length);
+ ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS
+ : FastCloneShallowArrayStub::CLONE_ELEMENTS;
+ FastCloneShallowArrayStub stub(mode, allocation_site_mode, length);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
}
@@ -5482,10 +5484,14 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
Register result,
Register source,
- int* offset) {
+ int* offset,
+ AllocationSiteMode mode) {
ASSERT(!source.is(r2));
ASSERT(!result.is(r2));
+ bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
+ object->map()->CanTrackAllocationSite();
+
// Only elements backing stores for non-COW arrays need to be copied.
Handle<FixedArrayBase> elements(object->elements());
bool has_elements = elements->length() > 0 &&
@@ -5495,8 +5501,13 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
// this object and its backing store.
int object_offset = *offset;
int object_size = object->map()->instance_size();
- int elements_offset = *offset + object_size;
int elements_size = has_elements ? elements->Size() : 0;
+ int elements_offset = *offset + object_size;
+ if (create_allocation_site_info) {
+ elements_offset += AllocationSiteInfo::kSize;
+ *offset += AllocationSiteInfo::kSize;
+ }
+
*offset += object_size + elements_size;
// Copy object header.
@@ -5521,7 +5532,8 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
__ add(r2, result, Operand(*offset));
__ str(r2, FieldMemOperand(result, total_offset));
__ LoadHeapObject(source, value_object);
- EmitDeepCopy(value_object, result, source, offset);
+ EmitDeepCopy(value_object, result, source, offset,
+ DONT_TRACK_ALLOCATION_SITE);
} else if (value->IsHeapObject()) {
__ LoadHeapObject(r2, Handle<HeapObject>::cast(value));
__ str(r2, FieldMemOperand(result, total_offset));
@@ -5531,6 +5543,14 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
}
}
+ // Build Allocation Site Info if desired
+ if (create_allocation_site_info) {
+ __ mov(r2, Operand(Handle<Map>(isolate()->heap()->
+ allocation_site_info_map())));
+ __ str(r2, FieldMemOperand(result, object_size));
+ __ str(source, FieldMemOperand(result, object_size + kPointerSize));
+ }
+
if (has_elements) {
// Copy elements backing store header.
__ LoadHeapObject(source, elements);
@@ -5566,7 +5586,8 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
__ add(r2, result, Operand(*offset));
__ str(r2, FieldMemOperand(result, total_offset));
__ LoadHeapObject(source, value_object);
- EmitDeepCopy(value_object, result, source, offset);
+ EmitDeepCopy(value_object, result, source, offset,
+ DONT_TRACK_ALLOCATION_SITE);
} else if (value->IsHeapObject()) {
__ LoadHeapObject(r2, Handle<HeapObject>::cast(value));
__ str(r2, FieldMemOperand(result, total_offset));
@@ -5617,7 +5638,8 @@ void LCodeGen::DoFastLiteral(LFastLiteral* instr) {
__ bind(&allocated);
int offset = 0;
__ LoadHeapObject(r1, instr->hydrogen()->boilerplate());
- EmitDeepCopy(instr->hydrogen()->boilerplate(), r0, r1, &offset);
+ EmitDeepCopy(instr->hydrogen()->boilerplate(), r0, r1, &offset,
+ instr->hydrogen()->allocation_site_mode());
ASSERT_EQ(size, offset);
}
View
3  src/arm/lithium-codegen-arm.h
@@ -365,7 +365,8 @@ class LCodeGen BASE_EMBEDDED {
void EmitDeepCopy(Handle<JSObject> object,
Register result,
Register source,
- int* offset);
+ int* offset,
+ AllocationSiteMode mode);
// Emit optimized code for integer division.
// Inputs are signed.
View
8 src/arm/stub-cache-arm.cc
@@ -1694,7 +1694,9 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall(
&try_holey_map);
__ mov(r2, receiver);
ElementsTransitionGenerator::
- GenerateMapChangeElementsTransition(masm());
+ GenerateMapChangeElementsTransition(masm(),
+ DONT_TRACK_ALLOCATION_SITE,
+ NULL);
__ jmp(&fast_object);
__ bind(&try_holey_map);
@@ -1705,7 +1707,9 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall(
&call_builtin);
__ mov(r2, receiver);
ElementsTransitionGenerator::
- GenerateMapChangeElementsTransition(masm());
+ GenerateMapChangeElementsTransition(masm(),
+ DONT_TRACK_ALLOCATION_SITE,
+ NULL);
__ bind(&fast_object);
} else {
__ CheckFastObjectElements(r3, r3, &call_builtin);
View
18 src/builtins.h
@@ -151,13 +151,13 @@ enum BuiltinExtraArguments {
Code::kNoExtraICState) \
V(KeyedLoadIC_PreMonomorphic, KEYED_LOAD_IC, PREMONOMORPHIC, \
Code::kNoExtraICState) \
- V(KeyedLoadIC_Generic, KEYED_LOAD_IC, MEGAMORPHIC, \
+ V(KeyedLoadIC_Generic, KEYED_LOAD_IC, GENERIC, \
Code::kNoExtraICState) \
- V(KeyedLoadIC_String, KEYED_LOAD_IC, MEGAMORPHIC, \
+ V(KeyedLoadIC_String, KEYED_LOAD_IC, GENERIC, \
Code::kNoExtraICState) \
- V(KeyedLoadIC_IndexedInterceptor, KEYED_LOAD_IC, MEGAMORPHIC, \
+ V(KeyedLoadIC_IndexedInterceptor, KEYED_LOAD_IC, GENERIC, \
Code::kNoExtraICState) \
- V(KeyedLoadIC_NonStrictArguments, KEYED_LOAD_IC, MEGAMORPHIC, \
+ V(KeyedLoadIC_NonStrictArguments, KEYED_LOAD_IC, GENERIC, \
Code::kNoExtraICState) \
\
V(StoreIC_Initialize, STORE_IC, UNINITIALIZED, \
@@ -168,7 +168,7 @@ enum BuiltinExtraArguments {
Code::kNoExtraICState) \
V(StoreIC_Megamorphic, STORE_IC, MEGAMORPHIC, \
Code::kNoExtraICState) \
- V(StoreIC_GlobalProxy, STORE_IC, MEGAMORPHIC, \
+ V(StoreIC_GlobalProxy, STORE_IC, GENERIC, \
Code::kNoExtraICState) \
V(StoreIC_Initialize_Strict, STORE_IC, UNINITIALIZED, \
kStrictMode) \
@@ -178,21 +178,21 @@ enum BuiltinExtraArguments {
kStrictMode) \
V(StoreIC_Megamorphic_Strict, STORE_IC, MEGAMORPHIC, \
kStrictMode) \
- V(StoreIC_GlobalProxy_Strict, STORE_IC, MEGAMORPHIC, \
+ V(StoreIC_GlobalProxy_Strict, STORE_IC, GENERIC, \
kStrictMode) \
V(StoreIC_Setter_ForDeopt, STORE_IC, MONOMORPHIC, \
kStrictMode) \
\
V(KeyedStoreIC_Initialize, KEYED_STORE_IC, UNINITIALIZED, \
Code::kNoExtraICState) \
- V(KeyedStoreIC_Generic, KEYED_STORE_IC, MEGAMORPHIC, \
+ V(KeyedStoreIC_Generic, KEYED_STORE_IC, GENERIC, \
Code::kNoExtraICState) \
\
V(KeyedStoreIC_Initialize_Strict, KEYED_STORE_IC, UNINITIALIZED, \
kStrictMode) \
- V(KeyedStoreIC_Generic_Strict, KEYED_STORE_IC, MEGAMORPHIC, \
+ V(KeyedStoreIC_Generic_Strict, KEYED_STORE_IC, GENERIC, \
kStrictMode) \
- V(KeyedStoreIC_NonStrictArguments, KEYED_STORE_IC, MEGAMORPHIC, \
+ V(KeyedStoreIC_NonStrictArguments, KEYED_STORE_IC, GENERIC, \
Code::kNoExtraICState) \
V(TransitionElementsSmiToDouble, BUILTIN, UNINITIALIZED, \
Code::kNoExtraICState) \
View
9 src/code-stubs.cc
@@ -570,15 +570,16 @@ bool ToBooleanStub::Types::CanBeUndetectable() const {
void ElementsTransitionAndStoreStub::Generate(MacroAssembler* masm) {
Label fail;
+ AllocationSiteMode mode = AllocationSiteInfo::GetMode(from_, to_);
ASSERT(!IsFastHoleyElementsKind(from_) || IsFastHoleyElementsKind(to_));
if (!FLAG_trace_elements_transitions) {
if (IsFastSmiOrObjectElementsKind(to_)) {
if (IsFastSmiOrObjectElementsKind(from_)) {
ElementsTransitionGenerator::
- GenerateMapChangeElementsTransition(masm);
+ GenerateMapChangeElementsTransition(masm, mode, &fail);
} else if (IsFastDoubleElementsKind(from_)) {
ASSERT(!IsFastSmiElementsKind(to_));
- ElementsTransitionGenerator::GenerateDoubleToObject(masm, &fail);
+ ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, &fail);
} else {
UNREACHABLE();
}
@@ -588,14 +589,14 @@ void ElementsTransitionAndStoreStub::Generate(MacroAssembler* masm) {
grow_mode_);
} else if (IsFastSmiElementsKind(from_) &&
IsFastDoubleElementsKind(to_)) {
- ElementsTransitionGenerator::GenerateSmiToDouble(masm, &fail);
+ ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, &fail);
KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(masm,
is_jsarray_,
grow_mode_);
} else if (IsFastDoubleElementsKind(from_)) {
ASSERT(to_ == FAST_HOLEY_DOUBLE_ELEMENTS);
ElementsTransitionGenerator::
- GenerateMapChangeElementsTransition(masm);
+ GenerateMapChangeElementsTransition(masm, mode, &fail);
} else {
UNREACHABLE();
}
View
21 src/code-stubs.h
@@ -427,14 +427,16 @@ class FastCloneShallowArrayStub : public PlatformCodeStub {
CLONE_DOUBLE_ELEMENTS,
COPY_ON_WRITE_ELEMENTS,
CLONE_ANY_ELEMENTS,
- CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO,
- LAST_CLONE_MODE = CLONE_ANY_ELEMENTS_WITH_ALLOCATION_SITE_INFO
+ LAST_CLONE_MODE = CLONE_ANY_ELEMENTS
};
static const int kFastCloneModeCount = LAST_CLONE_MODE + 1;
- FastCloneShallowArrayStub(Mode mode, int length)
+ FastCloneShallowArrayStub(Mode mode,
+ AllocationSiteMode allocation_site_mode,
+ int length)
: mode_(mode),
+ allocation_site_mode_(allocation_site_mode),
length_((mode == COPY_ON_WRITE_ELEMENTS) ? 0 : length) {
ASSERT_GE(length_, 0);
ASSERT_LE(length_, kMaximumClonedLength);
@@ -444,12 +446,21 @@ class FastCloneShallowArrayStub : public PlatformCodeStub {
private:
Mode mode_;
+ AllocationSiteMode allocation_site_mode_;
int length_;
+ class AllocationSiteModeBits: public BitField<AllocationSiteMode, 0, 1> {};
+ class ModeBits: public BitField<Mode, 1, 4> {};
+ class LengthBits: public BitField<int, 5, 4> {};
+ // Ensure data fits within available bits.
+ STATIC_ASSERT(LAST_ALLOCATION_SITE_MODE == 1);
+ STATIC_ASSERT(kFastCloneModeCount < 16);
+ STATIC_ASSERT(kMaximumClonedLength < 16);
Major MajorKey() { return FastCloneShallowArray; }
int MinorKey() {
- ASSERT(mode_ >= 0 && mode_ <= LAST_CLONE_MODE);
- return length_ * kFastCloneModeCount + mode_;
+ return AllocationSiteModeBits::encode(allocation_site_mode_)
+ | ModeBits::encode(mode_)
+ | LengthBits::encode(length_);
}
};
View
14 src/codegen.h
@@ -96,9 +96,17 @@ UnaryMathFunction CreateSqrtFunction();
class ElementsTransitionGenerator : public AllStatic {
public:
- static void GenerateMapChangeElementsTransition(MacroAssembler* masm);
- static void GenerateSmiToDouble(MacroAssembler* masm, Label* fail);
- static void GenerateDoubleToObject(MacroAssembler* masm, Label* fail);
+ // If |mode| is set to DONT_TRACK_ALLOCATION_SITE,
+ // |allocation_site_info_found| may be NULL.
+ static void GenerateMapChangeElementsTransition(MacroAssembler* masm,
+ AllocationSiteMode mode,
+ Label* allocation_site_info_found);
+ static void GenerateSmiToDouble(MacroAssembler* masm,
+ AllocationSiteMode mode,
+ Label* fail);
+ static void GenerateDoubleToObject(MacroAssembler* masm,
+ AllocationSiteMode mode,
+ Label* fail);
private:
DISALLOW_COPY_AND_ASSIGN(ElementsTransitionGenerator);
View
6 src/d8.cc
@@ -1235,12 +1235,6 @@ Handle<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
global_template->Set(String::New("Uint8ClampedArray"),
CreateArrayTemplate(Uint8ClampedArray), attr);
-#ifdef LIVE_OBJECT_LIST
- global_template->Set(String::New("lol_is_enabled"), True());
-#else
- global_template->Set(String::New("lol_is_enabled"), False());
-#endif
-
#if !defined(V8_SHARED) && !defined(_WIN32) && !defined(_WIN64)
Handle<ObjectTemplate> os_templ = ObjectTemplate::New();
AddOSMethods(os_templ);
View
617 src/d8.js
@@ -123,10 +123,6 @@ Debug.State = {
var trace_compile = false; // Tracing all compile events?
var trace_debug_json = false; // Tracing all debug json packets?
var last_cmd = '';
-//var lol_is_enabled; // Set to true in d8.cc if LIVE_OBJECT_LIST is defined.
-var lol_next_dump_index = 0;
-var kDefaultLolLinesToPrintAtATime = 10;
-var kMaxLolLinesToPrintAtATime = 1000;
var repeat_cmd_line = '';
var is_running = true;
// Global variable used to store whether a handle was requested.
@@ -507,13 +503,6 @@ function DebugRequest(cmd_line) {
this.request_ = void 0;
break;
- case 'liveobjectlist':
- case 'lol':
- if (lol_is_enabled) {
- this.request_ = this.lolToJSONRequest_(args, is_repeating);
- break;
- }
-
default:
throw new Error('Unknown command "' + cmd + '"');
}
@@ -558,53 +547,10 @@ DebugRequest.prototype.createRequest = function(command) {
};
-// Note: we use detected command repetition as a signal for continuation here.
-DebugRequest.prototype.createLOLRequest = function(command,
- start_index,
- lines_to_dump,
- is_continuation) {
- if (is_continuation) {
- start_index = lol_next_dump_index;
- }
-
- if (lines_to_dump) {
- lines_to_dump = parseInt(lines_to_dump);
- } else {
- lines_to_dump = kDefaultLolLinesToPrintAtATime;
- }
- if (lines_to_dump > kMaxLolLinesToPrintAtATime) {
- lines_to_dump = kMaxLolLinesToPrintAtATime;
- }
-
- // Save the next start_index to dump from:
- lol_next_dump_index = start_index + lines_to_dump;
-
- var request = this.createRequest(command);
- request.arguments = {};
- request.arguments.start = start_index;
- request.arguments.count = lines_to_dump;
-
- return request;
-};
-
-
// Create a JSON request for the evaluation command.
DebugRequest.prototype.makeEvaluateJSONRequest_ = function(expression) {
lookup_handle = null;
- if (lol_is_enabled) {
- // Check if the expression is a obj id in the form @<obj id>.
- var obj_id_match = expression.match(/^@([0-9]+)$/);
- if (obj_id_match) {
- var obj_id = parseInt(obj_id_match[1]);
- // Build a dump request.
- var request = this.createRequest('getobj');
- request.arguments = {};
- request.arguments.obj_id = obj_id;
- return request.toJSONProtocol();
- }
- }
-
// Check if the expression is a handle id in the form #<handle>#.
var handle_match = expression.match(/^#([0-9]*)#$/);
if (handle_match) {
@@ -1170,10 +1116,6 @@ DebugRequest.prototype.infoCommandToJSONRequest_ = function(args) {
// Build a evaluate request from the text command.
request = this.createRequest('frame');
last_cmd = 'info args';
- } else if (lol_is_enabled &&
- args && (args == 'liveobjectlist' || args == 'lol')) {
- // Build a evaluate request from the text command.
- return this.liveObjectListToJSONRequest_(null);
} else {
throw new Error('Invalid info arguments.');
}
@@ -1224,262 +1166,6 @@ DebugRequest.prototype.gcToJSONRequest_ = function(args) {
};
-// Args: [v[erbose]] [<N>] [i[ndex] <i>] [t[ype] <type>] [sp[ace] <space>]
-DebugRequest.prototype.lolMakeListRequest =
- function(cmd, args, first_arg_index, is_repeating) {
-
- var request;
- var start_index = 0;
- var dump_limit = void 0;
- var type_filter = void 0;
- var space_filter = void 0;
- var prop_filter = void 0;
- var is_verbose = false;
- var i;
-
- for (i = first_arg_index; i < args.length; i++) {
- var arg = args[i];
- // Check for [v[erbose]]:
- if (arg === 'verbose' || arg === 'v') {
- // Nothing to do. This is already implied by args.length > 3.
- is_verbose = true;
-
- // Check for [<N>]:
- } else if (arg.match(/^[0-9]+$/)) {
- dump_limit = arg;
- is_verbose = true;
-
- // Check for i[ndex] <i>:
- } else if (arg === 'index' || arg === 'i') {
- i++;
- if (args.length < i) {
- throw new Error('Missing index after ' + arg + '.');
- }
- start_index = parseInt(args[i]);
- // The user input start index starts at 1:
- if (start_index <= 0) {
- throw new Error('Invalid index ' + args[i] + '.');
- }
- start_index -= 1;
- is_verbose = true;
-
- // Check for t[ype] <type>:
- } else if (arg === 'type' || arg === 't') {
- i++;
- if (args.length < i) {
- throw new Error('Missing type after ' + arg + '.');
- }
- type_filter = args[i];
-
- // Check for space <heap space name>:
- } else if (arg === 'space' || arg === 'sp') {
- i++;
- if (args.length < i) {
- throw new Error('Missing space name after ' + arg + '.');
- }
- space_filter = args[i];
-
- // Check for property <prop name>:
- } else if (arg === 'property' || arg === 'prop') {
- i++;
- if (args.length < i) {
- throw new Error('Missing property name after ' + arg + '.');
- }
- prop_filter = args[i];
-
- } else {
- throw new Error('Unknown args at ' + arg + '.');
- }
- }
-
- // Build the verbose request:
- if (is_verbose) {
- request = this.createLOLRequest('lol-'+cmd,
- start_index,
- dump_limit,
- is_repeating);
- request.arguments.verbose = true;
- } else {
- request = this.createRequest('lol-'+cmd);
- request.arguments = {};
- }
-
- request.arguments.filter = {};
- if (type_filter) {
- request.arguments.filter.type = type_filter;
- }
- if (space_filter) {
- request.arguments.filter.space = space_filter;
- }
- if (prop_filter) {
- request.arguments.filter.prop = prop_filter;
- }
-
- return request;
-};
-
-
-function extractObjId(args) {
- var id = args;
- id = id.match(/^@([0-9]+)$/);
- if (id) {
- id = id[1];
- } else {
- throw new Error('Invalid obj id ' + args + '.');
- }
- return parseInt(id);
-}
-
-
-DebugRequest.prototype.lolToJSONRequest_ = function(args, is_repeating) {
- var request;
- // Use default command if one is not specified:
- if (!args) {
- args = 'info';
- }
-
- var orig_args = args;
- var first_arg_index;
-
- var arg, i;
- var args = args.split(/\s+/g);
- var cmd = args[0];
- var id;
-
- // Command: <id> [v[erbose]] ...
- if (cmd.match(/^[0-9]+$/)) {
- // Convert to the padded list command:
- // Command: l[ist] <dummy> <id> [v[erbose]] ...
-
- // Insert the implicit 'list' in front and process as normal:
- cmd = 'list';
- args.unshift(cmd);
- }
-
- switch(cmd) {
- // Command: c[apture]
- case 'capture':
- case 'c':
- request = this.createRequest('lol-capture');
- break;
-
- // Command: clear|d[elete] <id>|all
- case 'clear':
- case 'delete':
- case 'del': {
- if (args.length < 2) {
- throw new Error('Missing argument after ' + cmd + '.');
- } else if (args.length > 2) {
- throw new Error('Too many arguments after ' + cmd + '.');
- }
- id = args[1];
- if (id.match(/^[0-9]+$/)) {
- // Delete a specific lol record:
- request = this.createRequest('lol-delete');
- request.arguments = {};
- request.arguments.id = parseInt(id);
- } else if (id === 'all') {
- // Delete all:
- request = this.createRequest('lol-reset');
- } else {
- throw new Error('Invalid argument after ' + cmd + '.');
- }
- break;
- }
-
- // Command: diff <id1> <id2> [<dump options>]
- case 'diff':
- first_arg_index = 3;
-
- // Command: list <dummy> <id> [<dump options>]
- case 'list':
-
- // Command: ret[ainers] <obj id> [<dump options>]
- case 'retainers':
- case 'ret':
- case 'retaining-paths':
- case 'rp': {
- if (cmd === 'ret') cmd = 'retainers';
- else if (cmd === 'rp') cmd = 'retaining-paths';
-
- if (!first_arg_index) first_arg_index = 2;
-
- if (args.length < first_arg_index) {
- throw new Error('Too few arguments after ' + cmd + '.');
- }
-
- var request_cmd = (cmd === 'list') ? 'diff':cmd;
- request = this.lolMakeListRequest(request_cmd,
- args,
- first_arg_index,
- is_repeating);
-
- if (cmd === 'diff') {
- request.arguments.id1 = parseInt(args[1]);
- request.arguments.id2 = parseInt(args[2]);
- } else if (cmd == 'list') {
- request.arguments.id1 = 0;
- request.arguments.id2 = parseInt(args[1]);
- } else {
- request.arguments.id = extractObjId(args[1]);
- }
- break;
- }
-
- // Command: getid
- case 'getid': {
- request = this.createRequest('lol-getid');
- request.arguments = {};
- request.arguments.address = args[1];
- break;
- }
-
- // Command: inf[o] [<N>]
- case 'info':
- case 'inf': {
- if (args.length > 2) {
- throw new Error('Too many arguments after ' + cmd + '.');
- }
- // Built the info request:
- request = this.createLOLRequest('lol-info', 0, args[1], is_repeating);
- break;
- }
-
- // Command: path <obj id 1> <obj id 2>
- case 'path': {
- request = this.createRequest('lol-path');
- request.arguments = {};
- if (args.length > 2) {
- request.arguments.id1 = extractObjId(args[1]);
- request.arguments.id2 = extractObjId(args[2]);
- } else {
- request.arguments.id1 = 0;
- request.arguments.id2 = extractObjId(args[1]);
- }
- break;
- }
-
- // Command: print
- case 'print': {
- request = this.createRequest('lol-print');
- request.arguments = {};
- request.arguments.id = extractObjId(args[1]);
- break;
- }
-
- // Command: reset
- case 'reset': {
- request = this.createRequest('lol-reset');
- break;
- }
-
- default:
- throw new Error('Invalid arguments.');
- }
- return request.toJSONProtocol();
-};
-
-
// Create a JSON request for the threads command.
DebugRequest.prototype.threadsCommandToJSONRequest_ = function(args) {
// Build a threads request from the text command.
@@ -1545,7 +1231,6 @@ DebugRequest.prototype.helpCommand_ = function(args) {
print('inf[o] br[eak] - prints info about breakpoints in use');
print('inf[o] ar[gs] - prints info about arguments of the current function');
print('inf[o] lo[cals] - prints info about locals in the current function');
- print('inf[o] liveobjectlist|lol - same as \'lol info\'');
print('');
print('step [in | next | out| min [step count]]');
print('c[ontinue] - continue executing after a breakpoint');
@@ -1566,49 +1251,6 @@ DebugRequest.prototype.helpCommand_ = function(args) {
print('');
print('gc - runs the garbage collector');
print('');
-
- if (lol_is_enabled) {
- print('liveobjectlist|lol <command> - live object list tracking.');
- print(' where <command> can be:');
- print(' c[apture] - captures a LOL list.');
- print(' clear|del[ete] <id>|all - clears LOL of id <id>.');
- print(' If \'all\' is unspecified instead, will clear all.');
- print(' diff <id1> <id2> [<dump options>]');
- print(' - prints the diff between LOLs id1 and id2.');
- print(' - also see <dump options> below.');
- print(' getid <address> - gets the obj id for the specified address if available.');
- print(' The address must be in hex form prefixed with 0x.');
- print(' inf[o] [<N>] - lists summary info of all LOL lists.');
- print(' If N is specified, will print N items at a time.');
- print(' [l[ist]] <id> [<dump options>]');
- print(' - prints the listing of objects in LOL id.');
- print(' - also see <dump options> below.');
- print(' reset - clears all LOL lists.');
- print(' ret[ainers] <id> [<dump options>]');
- print(' - prints the list of retainers of obj id.');
- print(' - also see <dump options> below.');
- print(' path <id1> <id2> - prints the retaining path from obj id1 to id2.');
- print(' If only one id is specified, will print the path from');
- print(' roots to the specified object if available.');
- print(' print <id> - prints the obj for the specified obj id if available.');
- print('');
- print(' <dump options> includes:');
- print(' [v[erbose]] - do verbose dump.');
- print(' [<N>] - dump N items at a time. Implies verbose dump.');
- print(' If unspecified, N will default to '+
- kDefaultLolLinesToPrintAtATime+'. Max N is '+
- kMaxLolLinesToPrintAtATime+'.');
- print(' [i[ndex] <i>] - start dump from index i. Implies verbose dump.');
- print(' [t[ype] <type>] - filter by type.');
- print(' [sp[ace] <space name>] - filter by heap space where <space name> is one of');
- print(' { cell, code, lo, map, new, old-data, old-pointer }.');
- print('');
- print(' If the verbose option, or an option that implies a verbose dump');
- print(' is specified, then a verbose dump will requested. Else, a summary dump');
- print(' will be requested.');
- print('');
- }
-
print('trace compile');
// hidden command: trace debug json - toggles tracing of debug json packets
print('');
@@ -1709,237 +1351,6 @@ function refObjectToString_(protocolPackage, handle) {
}
-function decodeLolCaptureResponse(body) {
- var result;
- result = 'Captured live object list '+ body.id +
- ': count '+ body.count + ' size ' + body.size;
- return result;
-}
-
-
-function decodeLolDeleteResponse(body) {
- var result;
- result = 'Deleted live object list '+ body.id;
- return result;
-}
-
-
-function digitsIn(value) {
- var digits = 0;
- if (value === 0) value = 1;
- while (value >= 1) {
- digits++;
- value /= 10;
- }
- return digits;
-}
-
-
-function padding(value, max_digits) {
- var padding_digits = max_digits - digitsIn(value);
- var padding = '';
- while (padding_digits > 0) {
- padding += ' ';
- padding_digits--;
- }
- return padding;
-}
-
-
-function decodeLolInfoResponse(body) {
- var result;
- var lists = body.lists;
- var length = lists.length;
- var first_index = body.first_index + 1;
- var has_more = ((first_index + length) <= body.count);
- result = 'captured live object lists';
- if (has_more || (first_index != 1)) {
- result += ' ['+ length +' of '+ body.count +
- ': starting from '+ first_index +']';
- }
- result += ':\n';
- var max_digits = digitsIn(body.count);
- var last_count = 0;
- var last_size = 0;
- for (var i = 0; i < length; i++) {
- var entry = lists[i];
- var count = entry.count;
- var size = entry.size;
- var index = first_index + i;
- result += ' [' + padding(index, max_digits) + index + '] id '+ entry.id +
- ': count '+ count;
- if (last_count > 0) {
- result += '(+' + (count - last_count) + ')';
- }
- result += ' size '+ size;
- if (last_size > 0) {
- result += '(+' + (size - last_size) + ')';
- }
- result += '\n';
- last_count = count;
- last_size = size;
- }
- result += ' total: '+length+' lists\n';
- if (has_more) {
- result += ' -- press <enter> for more --\n';
- } else {
- repeat_cmd_line = '';
- }
- if (length === 0) result += ' none\n';
-
- return result;
-}
-
-
-function decodeLolListResponse(body, title) {
-
- var result;
- var total_count = body.count;
- var total_size = body.size;
- var length;
- var max_digits;
- var i;
- var entry;
- var index;
-
- var max_count_digits = digitsIn(total_count);
- var max_size_digits;
-
- var summary = body.summary;
- if (summary) {
-
- var roots_count = 0;
- var found_root = body.found_root || 0;
- var found_weak_root = body.found_weak_root || 0;
-
- // Print the summary result:
- result = 'summary of objects:\n';
- length = summary.length;
- if (found_root !== 0) {
- roots_count++;
- }
- if (found_weak_root !== 0) {
- roots_count++;
- }
- max_digits = digitsIn(length + roots_count);
- max_size_digits = digitsIn(total_size);
-
- index = 1;
- if (found_root !== 0) {
- result += ' [' + padding(index, max_digits) + index + '] ' +
- ' count '+ 1 + padding(0, max_count_digits) +
- ' '+ padding(0, max_size_digits+1) +
- ' : <root>\n';
- index++;
- }
- if (found_weak_root !== 0) {
- result += ' [' + padding(index, max_digits) + index + '] ' +
- ' count '+ 1 + padding(0, max_count_digits) +
- ' '+ padding(0, max_size_digits+1) +
- ' : <weak root>\n';
- index++;
- }
-
- for (i = 0; i < length; i++) {
- entry = summary[i];
- var count = entry.count;
- var size = entry.size;
- result += ' [' + padding(index, max_digits) + index + '] ' +
- ' count '+ count + padding(count, max_count_digits) +
- ' size '+ size + padding(size, max_size_digits) +
- ' : <' + entry.desc + '>\n';
- index++;
- }
- result += '\n total count: '+(total_count+roots_count)+'\n';
- if (body.size) {
- result += ' total size: '+body.size+'\n';
- }
-
- } else {
- // Print the full dump result:
- var first_index = body.first_index + 1;
- var elements = body.elements;
- length = elements.length;
- var has_more = ((first_index + length) <= total_count);
- result = title;
- if (has_more || (first_index != 1)) {
- result += ' ['+ length +' of '+ total_count +
- ': starting from '+ first_index +']';
- }
- result += ':\n';
- if (length === 0) result += ' none\n';
- max_digits = digitsIn(length);
-
- var max_id = 0;
- var max_size = 0;
- for (i = 0; i < length; i++) {
- entry = elements[i];
- if (entry.id > max_id) max_id = entry.id;
- if (entry.size > max_size) max_size = entry.size;
- }
- var max_id_digits = digitsIn(max_id);
- max_size_digits = digitsIn(max_size);
-
- for (i = 0; i < length; i++) {
- entry = elements[i];
- index = first_index + i;
- result += ' ['+ padding(index, max_digits) + index +']';
- if (entry.id !== 0) {
- result += ' @' + entry.id + padding(entry.id, max_id_digits) +
- ': size ' + entry.size + ', ' +
- padding(entry.size, max_size_digits) + entry.desc + '\n';
- } else {
- // Must be a root or weak root:
- result += ' ' + entry.desc + '\n';
- }
- }
- if (has_more) {
- result += ' -- press <enter> for more --\n';
- } else {
- repeat_cmd_line = '';
- }
- if (length === 0) result += ' none\n';
- }
-
- return result;
-}
-
-
-function decodeLolDiffResponse(body) {
- var title = 'objects';
- return decodeLolListResponse(body, title);
-}
-
-
-function decodeLolRetainersResponse(body) {
- var title = 'retainers for @' + body.id;
- return decodeLolListResponse(body, title);
-}
-
-
-function decodeLolPathResponse(body) {
- return body.path;
-}
-
-
-function decodeLolResetResponse(body) {
- return 'Reset all live object lists.';
-}
-
-
-function decodeLolGetIdResponse(body) {
- if (body.id == 0) {
- return 'Address is invalid, or object has been moved or collected';
- }
- return 'obj id is @' + body.id;
-}
-
-
-function decodeLolPrintResponse(body) {
- return body.dump;
-}
-
-
// Rounds number 'num' to 'length' decimal places.
function roundNumber(num, length) {
var factor = Math.pow(10, length);
@@ -2276,34 +1687,6 @@ function DebugResponseDetails(response) {
}
break;
- case 'lol-capture':
- details.text = decodeLolCaptureResponse(body);
- break;
- case 'lol-delete':
- details.text = decodeLolDeleteResponse(body);
- break;
- case 'lol-diff':
- details.text = decodeLolDiffResponse(body);
- break;
- case 'lol-getid':
- details.text = decodeLolGetIdResponse(body);
- break;
- case 'lol-info':
- details.text = decodeLolInfoResponse(body);
- break;
- case 'lol-print':
- details.text = decodeLolPrintResponse(body);
- break;
- case 'lol-reset':
- details.text = decodeLolResetResponse(body);
- break;
- case 'lol-retainers':
- details.text = decodeLolRetainersResponse(body);
- break;
- case 'lol-path':
- details.text = decodeLolPathResponse(body);
- break;
-
default:
details.text =
'Response for unknown command \'' + response.command() + '\'' +
View
123 src/debug-debugger.js
@@ -110,7 +110,6 @@ var debugger_flags = {
}
},
};
-var lol_is_enabled = %HasLOLEnabled();
// Create a new break point object and add it to the list of break points.
@@ -1437,8 +1436,6 @@ DebugCommandProcessor.prototype.processDebugJSONRequest = function(
this.setVariableValueRequest_(request, response);
} else if (request.command == 'evaluate') {
this.evaluateRequest_(request, response);
- } else if (lol_is_enabled && request.command == 'getobj') {
- this.getobjRequest_(request, response);
} else if (request.command == 'lookup') {
this.lookupRequest_(request, response);
} else if (request.command == 'references') {
@@ -1468,28 +1465,6 @@ DebugCommandProcessor.prototype.processDebugJSONRequest = function(
} else if (request.command == 'gc') {
this.gcRequest_(request, response);
- // LiveObjectList tools:
- } else if (lol_is_enabled && request.command == 'lol-capture') {
- this.lolCaptureRequest_(request, response);
- } else if (lol_is_enabled && request.command == 'lol-delete') {
- this.lolDeleteRequest_(request, response);
- } else if (lol_is_enabled && request.command == 'lol-diff') {
- this.lolDiffRequest_(request, response);
- } else if (lol_is_enabled && request.command == 'lol-getid') {
- this.lolGetIdRequest_(request, response);
- } else if (lol_is_enabled && request.command == 'lol-info') {
- this.lolInfoRequest_(request, response);
- } else if (lol_is_enabled && request.command == 'lol-reset') {
- this.lolResetRequest_(request, response);
- } else if (lol_is_enabled && request.command == 'lol-retainers') {
- this.lolRetainersRequest_(request, response);
- } else if (lol_is_enabled && request.command == 'lol-path') {
- this.lolPathRequest_(request, response);
- } else if (lol_is_enabled && request.command == 'lol-print') {
- this.lolPrintRequest_(request, response);
- } else if (lol_is_enabled && request.command == 'lol-stats') {
- this.lolStatsRequest_(request, response);
-
} else {
throw new Error('Unknown command "' + request.command + '" in request');
}
@@ -2191,24 +2166,6 @@ DebugCommandProcessor.prototype.evaluateRequest_ = function(request, response) {
};
-DebugCommandProcessor.prototype.getobjRequest_ = function(request, response) {
- if (!request.arguments) {
- return response.failed('Missing arguments');
- }
-
- // Pull out arguments.
- var obj_id = request.arguments.obj_id;
-
- // Check for legal arguments.
- if (IS_UNDEFINED(obj_id)) {
- return response.failed('Argument "obj_id" missing');
- }
-
- // Dump the object.
- response.body = MakeMirror(%GetLOLObj(obj_id));
-};
-
-
DebugCommandProcessor.prototype.lookupRequest_ = function(request, response) {
if (!request.arguments) {
return response.failed('Missing arguments');
@@ -2567,86 +2524,6 @@ DebugCommandProcessor.prototype.gcRequest_ = function(request, response) {
};
-DebugCommandProcessor.prototype.lolCaptureRequest_ =
- function(request, response) {
- response.body = %CaptureLOL();
-};
-
-
-DebugCommandProcessor.prototype.lolDeleteRequest_ =
- function(request, response) {
- var id = request.arguments.id;
- var result = %DeleteLOL(id);
- if (result) {
- response.body = { id: id };
- } else {
- response.failed('Failed to delete: live object list ' + id + ' not found.');
- }
-};
-
-
-DebugCommandProcessor.prototype.lolDiffRequest_ = function(request, response) {
- var id1 = request.arguments.id1;
- var id2 = request.arguments.id2;
- var verbose = request.arguments.verbose;
- var filter = request.arguments.filter;
- if (verbose === true) {
- var start = request.arguments.start;
- var count = request.arguments.count;
- response.body = %DumpLOL(id1, id2, start, count, filter);
- } else {
- response.body = %SummarizeLOL(id1, id2, filter);
- }
-};
-
-
-DebugCommandProcessor.prototype.lolGetIdRequest_ = function(request, response) {
- var address = request.arguments.address;
- response.body = {};
- response.body.id = %GetLOLObjId(address);
-};
-
-
-DebugCommandProcessor.prototype.lolInfoRequest_ = function(request, response) {
- var start = request.arguments.start;
- var count = request.arguments.count;
- response.body = %InfoLOL(start, count);
-};
-
-
-DebugCommandProcessor.prototype.lolResetRequest_ = function(request, response) {
- %ResetLOL();
-};
-
-
-DebugCommandProcessor.prototype.lolRetainersRequest_ =
- function(request, response) {
- var id = request.arguments.id;
- var verbose = request.arguments.verbose;
- var start = request.arguments.start;
- var count = request.arguments.count;
- var filter = request.arguments.filter;
-
- response.body = %GetLOLObjRetainers(id, Mirror.prototype, verbose,
- start, count, filter);
-};
-
-
-DebugCommandProcessor.prototype.lolPathRequest_ = function(request, response) {
- var id1 = request.arguments.id1;
- var id2 = request.arguments.id2;
- response.body = {};
- response.body.path = %GetLOLPath(id1, id2, Mirror.prototype);
-};
-
-
-DebugCommandProcessor.prototype.lolPrintRequest_ = function(request, response) {
- var id = request.arguments.id;
- response.body = {};
- response.body.dump = %PrintLOLObj(id);
-};
-
-
// Check whether the previously processed command caused the VM to become
// running.
DebugCommandProcessor.prototype.isRunning = function() {
View
8 src/flag-definitions.h
@@ -194,6 +194,8 @@ DEFINE_bool(trace_all_uses, false, "trace all use positions")
DEFINE_bool(trace_range, false, "trace range analysis")
DEFINE_bool(trace_gvn, false, "trace global value numbering")
DEFINE_bool(trace_representation, false, "trace representation types")
+DEFINE_bool(trace_track_allocation_sites, false,
+ "trace the tracking of allocation sites")
DEFINE_bool(stress_pointer_maps, false, "pointer map for every instruction")
DEFINE_bool(stress_environments, false, "environment for every instruction")
DEFINE_int(deopt_every_n_times,
@@ -419,12 +421,6 @@ DEFINE_bool(use_idle_notification, true,
// ic.cc
DEFINE_bool(use_ic, true, "use inline caching")
-#ifdef LIVE_OBJECT_LIST
-// liveobjectlist.cc
-DEFINE_string(lol_workdir, NULL, "path for lol temp files")
-DEFINE_bool(verify_lol, false, "perform debugging verification for lol")
-#endif
-
// macro-assembler-ia32.cc
DEFINE_bool(native_code_counters, false,
"generate extra code for manipulating stats counters")
View
9 src/global-handles.cc
@@ -59,7 +59,14 @@ class GlobalHandles::Node {
return reinterpret_cast<Node*>(location);
}
- Node() {}
+ Node() {
+ ASSERT(OFFSET_OF(Node, flags_) == Internals::kNodeFlagsOffset);
+ ASSERT(OFFSET_OF(Node, class_id_) == Internals::kNodeClassIdOffset);
+ ASSERT(static_cast<int>(IsIndependent::kShift) ==
+ Internals::kNodeIsIndependentShift);
+ ASSERT(static_cast<int>(IsPartiallyDependent::kShift) ==
+ Internals::kNodeIsPartiallyDependentShift);
+ }
#ifdef DEBUG
~Node() {
View
4 src/heap-inl.h
@@ -633,20 +633,24 @@ void ExternalStringTable::Verify() {
// TODO(yangguo): check that the object is indeed an external string.
ASSERT(heap_->InNewSpace(obj));
ASSERT(obj != HEAP->the_hole_value());
+#ifndef ENABLE_LATIN_1
if (obj->IsExternalAsciiString()) {
ExternalAsciiString* string = ExternalAsciiString::cast(obj);
ASSERT(String::IsAscii(string->GetChars(), string->length()));
}
+#endif
}
for (int i = 0; i < old_space_strings_.length(); ++i) {
Object* obj = Object::cast(old_space_strings_[i]);
// TODO(yangguo): check that the object is indeed an external string.
ASSERT(!heap_->InNewSpace(obj));
ASSERT(obj != HEAP->the_hole_value());
+#ifndef ENABLE_LATIN_1
if (obj->IsExternalAsciiString()) {
ExternalAsciiString* string = ExternalAsciiString::cast(obj);
ASSERT(String::IsAscii(string->GetChars(), string->length()));
}
+#endif
}
#endif
}
View
42 src/heap.cc
@@ -37,7 +37,6 @@
#include "global-handles.h"
#include "heap-profiler.h"
#include "incremental-marking.h"
-#include "liveobjectlist-inl.h"
#include "mark-compact.h"
#include "natives.h"
#include "objects-visiting.h"
@@ -439,7 +438,6 @@ void Heap::GarbageCollectionPrologue() {
ReportStatisticsBeforeGC();
#endif // DEBUG
- LiveObjectList::GCPrologue();
store_buffer()->GCPrologue();
}
@@ -466,7 +464,6 @@ void Heap::RepairFreeListsAfterBoot() {
void Heap::GarbageCollectionEpilogue() {
store_buffer()->GCEpilogue();
- LiveObjectList::GCEpilogue();
// In release mode, we only zap the from space under heap verification.
if (Heap::ShouldZapGarbage()) {
@@ -888,6 +885,7 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
if (collector == MARK_COMPACTOR && global_gc_prologue_callback_) {
ASSERT(!allocation_allowed_);
GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
+ VMState state(isolate_, EXTERNAL);
global_gc_prologue_callback_();
}
@@ -896,6 +894,7 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
{
GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
+ VMState state(isolate_, EXTERNAL);
for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) {
if (gc_type & gc_prologue_callbacks_[i].gc_type) {
gc_prologue_callbacks_[i].callback(gc_type, kNoGCCallbackFlags);
@@ -1009,6 +1008,7 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
{
GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
+ VMState state(isolate_, EXTERNAL);
GCCallbackFlags callback_flags = kNoGCCallbackFlags;
for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) {
if (gc_type & gc_epilogue_callbacks_[i].gc_type) {
@@ -1020,6 +1020,7 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
if (collector == MARK_COMPACTOR && global_gc_epilogue_callback_) {
ASSERT(!allocation_allowed_);
GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
+ VMState state(isolate_, EXTERNAL);
global_gc_epilogue_callback_();
}
@@ -1389,7 +1390,6 @@ void Heap::Scavenge() {
promotion_queue_.Destroy();
- LiveObjectList::UpdateReferencesForScavengeGC();
if (!FLAG_watch_ic_patching) {
isolate()->runtime_profiler()->UpdateSamplesAfterScavenge();
}
@@ -4394,7 +4394,8 @@ MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) {
}
-MaybeObject* Heap::CopyJSObject(JSObject* source) {
+MaybeObject* Heap::CopyJSObject(JSObject* source,
+ AllocationSiteMode mode) {
// Never used to copy functions. If functions need to be copied we
// have to be careful to clear the literals array.
SLOW_ASSERT(!source->IsJSFunction());
@@ -4404,13 +4405,25 @@ MaybeObject* Heap::CopyJSObject(JSObject* source) {
int object_size = map->instance_size();
Object* clone;
+ bool track_origin = mode == TRACK_ALLOCATION_SITE &&
+ map->CanTrackAllocationSite();
+
WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER;
// If we're forced to always allocate, we use the general allocation
// functions which may leave us with an object in old space.
+ int adjusted_object_size = object_size;
if (always_allocate()) {
+ // We'll only track origin if we are certain to allocate in new space
+ if (track_origin) {
+ const int kMinFreeNewSpaceAfterGC = InitialSemiSpaceSize() * 3/4;
+ if ((object_size + AllocationSiteInfo::kSize) < kMinFreeNewSpaceAfterGC) {
+ adjusted_object_size += AllocationSiteInfo::kSize;
+ }
+ }
+
{ MaybeObject* maybe_clone =
- AllocateRaw(object_size, NEW_SPACE, OLD_POINTER_SPACE);
+ AllocateRaw(adjusted_object_size, NEW_SPACE, OLD_POINTER_SPACE);
if (!maybe_clone->ToObject(&clone)) return maybe_clone;
}
Address clone_address = HeapObject::cast(clone)->address();
@@ -4423,7 +4436,11 @@ MaybeObject* Heap::CopyJSObject(JSObject* source) {
(object_size - JSObject::kHeaderSize) / kPointerSize);
} else {
wb_mode = SKIP_WRITE_BARRIER;
- { MaybeObject* maybe_clone = new_space_.AllocateRaw(object_size);
+ if (track_origin) {
+ adjusted_object_size += AllocationSiteInfo::kSize;
+ }
+
+ { MaybeObject* maybe_clone = new_space_.AllocateRaw(adjusted_object_size);
if (!maybe_clone->ToObject(&clone)) return maybe_clone;
}
SLOW_ASSERT(InNewSpace(clone));
@@ -4434,6 +4451,13 @@ MaybeObject* Heap::CopyJSObject(JSObject* source) {
object_size);
}
+ if (adjusted_object_size > object_size) {
+ AllocationSiteInfo* alloc_info = reinterpret_cast<AllocationSiteInfo*>(
+ reinterpret_cast<Address>(clone) + object_size);
+ alloc_info->set_map(allocation_site_info_map());
+ alloc_info->set_payload(source);
+ }
+
SLOW_ASSERT(
JSObject::cast(clone)->GetElementsKind() == source->GetElementsKind());
FixedArrayBase* elements = FixedArrayBase::cast(source->elements());
@@ -6744,7 +6768,7 @@ void HeapIterator::reset() {
}
-#if defined(DEBUG) || defined(LIVE_OBJECT_LIST)
+#ifdef DEBUG
Object* const PathTracer::kAnyGlobalObject = reinterpret_cast<Object*>(NULL);
@@ -6911,10 +6935,8 @@ void PathTracer::ProcessResults() {
PrintF("=====================================\n");
}
}
-#endif // DEBUG || LIVE_OBJECT_LIST
-#ifdef DEBUG
// Triggers a depth-first traversal of reachable objects from one
// given root object and finds a path to a specific heap object and
// prints it.
View
8 src/heap.h
@@ -624,7 +624,9 @@ class Heap {
// Returns a deep copy of the JavaScript object.
// Properties and elements are copied too.
// Returns failure if allocation failed.
- MUST_USE_RESULT MaybeObject* CopyJSObject(JSObject* source);
+ MUST_USE_RESULT MaybeObject* CopyJSObject(
+ JSObject* source,
+ AllocationSiteMode mode = DONT_TRACK_ALLOCATION_SITE);
// Allocates the function prototype.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
@@ -2840,7 +2842,7 @@ class IntrusiveMarking {
};
-#if defined(DEBUG) || defined(LIVE_OBJECT_LIST)
+#ifdef DEBUG
// Helper class for tracing paths to a search target Object from all roots.
// The TracePathFrom() method can be used to trace paths from a specific
// object to the search target object.
@@ -2897,7 +2899,7 @@ class PathTracer : public ObjectVisitor {
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer);
};
-#endif // DEBUG || LIVE_OBJECT_LIST
+#endif // DEBUG
} } // namespace v8::internal
View
7 src/hydrogen-instructions.cc
@@ -801,6 +801,13 @@ void HClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
}
+void HWrapReceiver::PrintDataTo(StringStream* stream) {
+ receiver()->PrintNameTo(stream);
+ stream->Add(" ");
+ function()->PrintNameTo(stream);
+}
+
+
void HAccessArgumentsAt::PrintDataTo(StringStream* stream) {
arguments()->PrintNameTo(stream);
stream->Add("[");
View
26 src/hydrogen-instructions.h
@@ -2835,6 +2835,8 @@ class HWrapReceiver: public HTemplateInstruction<2> {
virtual HValue* Canonicalize();
+ virtual void PrintDataTo(StringStream* stream);
+
DECLARE_CONCRETE_INSTRUCTION(WrapReceiver)
};
@@ -4966,19 +4968,29 @@ class HAllocateObject: public HTemplateInstruction<1> {
template <int V>
class HMaterializedLiteral: public HTemplateInstruction<V> {
public:
+ HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode)
+ : literal_index_(index), depth_(depth), allocation_site_mode_(mode) {
+ this->set_representation(Representation::Tagged());
+ }
+
HMaterializedLiteral<V>(int index, int depth)
- : literal_index_(index), depth_(depth) {
+ : literal_index_(index), depth_(depth),
+ allocation_site_mode_(DONT_TRACK_ALLOCATION_SITE) {
this->set_representation(Representation::Tagged());
}
int literal_index() const { return literal_index_; }
int depth() const { return depth_; }
+ AllocationSiteMode allocation_site_mode() const {
+ return allocation_site_mode_;
+ }
private:
virtual bool IsDeletable() const { return true; }
int literal_index_;
int depth_;
+ AllocationSiteMode allocation_site_mode_;
};
@@ -4988,8 +5000,9 @@ class HFastLiteral: public HMaterializedLiteral<1> {
Handle<JSObject> boilerplate,
int total_size,
int literal_index,
- int depth)
- : HMaterializedLiteral<1>(literal_index, depth),
+ int depth,
+ AllocationSiteMode mode)
+ : HMaterializedLiteral<1>(literal_index, depth, mode),
boilerplate_(boilerplate),
total_size_(total_size) {
SetOperandAt(0, context);
@@ -5004,7 +5017,6 @@ class HFastLiteral: public HMaterializedLiteral<1> {
HValue* context() { return OperandAt(0); }
Handle<JSObject> boilerplate() const { return boilerplate_; }
int total_size() const { return total_size_; }
-
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
}
@@ -5024,8 +5036,9 @@ class HArrayLiteral: public HMaterializedLiteral<1> {
Handle<HeapObject> boilerplate_object,
int length,
int literal_index,
- int depth)
- : HMaterializedLiteral<1>(literal_index, depth),
+ int depth,
+ AllocationSiteMode mode)
+ : HMaterializedLiteral<1>(literal_index, depth, mode),
length_(length),
boilerplate_object_(boilerplate_object) {
SetOperandAt(0, context);
@@ -5041,7 +5054,6 @@ class HArrayLiteral: public HMaterializedLiteral<1> {
}
Handle<HeapObject> boilerplate_object() const { return boilerplate_object_; }
int length() const { return length_; }
-
bool IsCopyOnWrite() const;
virtual Representation RequiredInputRepresentation(int index) {
View
25 src/hydrogen.cc
@@ -5213,7 +5213,8 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
boilerplate_object,
total_size,
expr->literal_index(),
- expr->depth());
+ expr->depth(),
+ DONT_TRACK_ALLOCATION_SITE);
} else {
literal = new(zone()) HObjectLiteral(context,
expr->constant_properties(),
@@ -5323,7 +5324,13 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
Handle<JSObject> boilerplate = Handle<JSObject>::cast(raw_boilerplate);
ElementsKind boilerplate_elements_kind =
- Handle<JSObject>::cast(boilerplate)->GetElementsKind();
+ Handle<JSObject>::cast(boilerplate)->GetElementsKind();
+
+ // TODO(mvstanton): This heuristic is only a temporary solution. In the
+ // end, we want to quit creating allocation site info after a certain number
+ // of GCs for a call site.
+ AllocationSiteMode mode = AllocationSiteInfo::GetMode(
+ boilerplate_elements_kind);
// Check whether to use fast or slow deep-copying for boilerplate.
int total_size = 0;
@@ -5332,17 +5339,22 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
HFastLiteral::kMaxLiteralDepth,
&max_properties,
&total_size)) {
+ if (mode == TRACK_ALLOCATION_SITE) {
+ total_size += AllocationSiteInfo::kSize;
+ }
literal = new(zone()) HFastLiteral(context,
boilerplate,
total_size,
expr->literal_index(),
- expr->depth());
+ expr->depth(),
+ mode);
} else {
literal = new(zone()) HArrayLiteral(context,
boilerplate,
length,
expr->literal_index(),