Version 3.12.4
Removed -fomit-frame-pointer flag from Release builds to make the stack walkable by TCMalloc (Chromium issue 133723).
Ported r7868 (constant masking) to x64 (issue 1374).
Expose more detailed memory statistics (issue 2201).
Fixed Harmony Maps and WeakMaps for undefined values (Chromium issue 132744).
Correctly throw reference error in strict mode with ICs disabled (issue 2119).
Performance and stability improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@11937 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index a0ec3e6..6663c66 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2012-06-27: Version 3.12.4
+
+ Removed -fomit-frame-pointer flag from Release builds to make
+ the stack walkable by TCMalloc (Chromium issue 133723).
+
+ Ported r7868 (constant masking) to x64 (issue 1374).
+
+ Expose more detailed memory statistics (issue 2201).
+
+ Fixed Harmony Maps and WeakMaps for undefined values
+ (Chromium issue 132744).
+
+ Correctly throw reference error in strict mode with ICs disabled
+ (issue 2119).
+
+ Performance and stability improvements on all platforms.
+
+
2012-06-25: Version 3.12.3
Reverted r11835 'Unify promotion and allocation limit computation' due
diff --git a/build/common.gypi b/build/common.gypi
index ae6b2a7..a50ccbd 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -348,7 +348,6 @@
'cflags': [
'-fdata-sections',
'-ffunction-sections',
- '-fomit-frame-pointer',
'-O3',
],
'conditions': [
@@ -378,15 +377,17 @@
'InlineFunctionExpansion': '2',
'EnableIntrinsicFunctions': 'true',
'FavorSizeOrSpeed': '0',
- 'OmitFramePointers': 'true',
'StringPooling': 'true',
-
'conditions': [
['OS=="win" and component=="shared_library"', {
'RuntimeLibrary': '2', #/MD
}, {
'RuntimeLibrary': '0', #/MT
}],
+ ['v8_target_arch=="x64"', {
+ # TODO(2207): remove this option once the bug is fixed.
+ 'WholeProgramOptimization': 'true',
+ }],
],
},
'VCLinkerTool': {
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index fd93480..404f3c6 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -396,7 +396,7 @@
Code::Flags flags = Code::ComputeFlags(kind,
MONOMORPHIC,
extra_state,
- NORMAL,
+ Code::NORMAL,
argc);
Isolate::Current()->stub_cache()->GenerateProbe(
masm, flags, r1, r2, r3, r4, r5, r6);
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 7fc8138..54114db 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -1526,7 +1526,7 @@
GenerateMissBranch();
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -2071,7 +2071,7 @@
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2217,7 +2217,7 @@
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2316,7 +2316,7 @@
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2533,7 +2533,7 @@
GenerateMissBranch();
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2591,7 +2591,7 @@
GenerateMissBranch();
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2619,7 +2619,9 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
@@ -2664,7 +2666,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2709,7 +2711,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2754,7 +2756,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2800,7 +2802,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2835,7 +2837,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NONEXISTENT, factory()->empty_string());
+ return GetCode(Code::NONEXISTENT, factory()->empty_string());
}
@@ -2855,7 +2857,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -2876,7 +2878,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2914,7 +2916,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2934,7 +2936,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -2956,7 +2958,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2998,7 +3000,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -3021,7 +3023,7 @@
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -3046,7 +3048,7 @@
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3071,7 +3073,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -3097,7 +3099,7 @@
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -3118,7 +3120,7 @@
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3144,7 +3146,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3169,7 +3171,7 @@
__ DecrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3189,7 +3191,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -3217,7 +3219,7 @@
__ Jump(miss_ic, RelocInfo::CODE_TARGET, al);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
@@ -3256,7 +3258,9 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
@@ -3280,7 +3284,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -3319,7 +3323,7 @@
__ Jump(miss_ic, RelocInfo::CODE_TARGET, al);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
diff --git a/src/ast.cc b/src/ast.cc
index b790e25..fb9db7c 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -520,9 +520,11 @@
return false;
case MAP_TRANSITION:
case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
// Perhaps something interesting is up in the prototype chain...
break;
+ case NONEXISTENT:
+ UNREACHABLE();
+ break;
}
}
// If we reach the end of the prototype chain, we don't know the target.
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index b67deae..e910a43 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -2193,13 +2193,13 @@
}
case MAP_TRANSITION:
case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
// Ignore non-properties.
break;
case NORMAL:
// Do not occur since the from object has fast properties.
case HANDLER:
case INTERCEPTOR:
+ case NONEXISTENT:
// No element in instance descriptors have proxy or interceptor type.
UNREACHABLE();
break;
diff --git a/src/collection.js b/src/collection.js
index 9ca0aae..d36fe18 100644
--- a/src/collection.js
+++ b/src/collection.js
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -129,7 +129,7 @@
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
- return !IS_UNDEFINED(%MapGet(this, key));
+ return %MapHas(this, key);
}
@@ -141,12 +141,7 @@
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
- if (!IS_UNDEFINED(%MapGet(this, key))) {
- %MapSet(this, key, void 0);
- return true;
- } else {
- return false;
- }
+ return %MapDelete(this, key);
}
@@ -191,7 +186,7 @@
if (!IS_SPEC_OBJECT(key)) {
throw %MakeTypeError('invalid_weakmap_key', [this, key]);
}
- return !IS_UNDEFINED(%WeakMapGet(this, key));
+ return %WeakMapHas(this, key);
}
@@ -203,12 +198,7 @@
if (!IS_SPEC_OBJECT(key)) {
throw %MakeTypeError('invalid_weakmap_key', [this, key]);
}
- if (!IS_UNDEFINED(%WeakMapGet(this, key))) {
- %WeakMapSet(this, key, void 0);
- return true;
- } else {
- return false;
- }
+ return %WeakMapDelete(this, key);
}
// -------------------------------------------------------------------
diff --git a/src/disassembler.cc b/src/disassembler.cc
index e3b40ab..9f8b9a8 100644
--- a/src/disassembler.cc
+++ b/src/disassembler.cc
@@ -244,8 +244,8 @@
out.AddFormatted(" %s, %s", Code::Kind2String(kind),
Code::ICState2String(ic_state));
if (ic_state == MONOMORPHIC) {
- PropertyType type = code->type();
- out.AddFormatted(", %s", Code::PropertyType2String(type));
+ Code::StubType type = code->type();
+ out.AddFormatted(", %s", Code::StubType2String(type));
}
if (kind == Code::CALL_IC || kind == Code::KEYED_CALL_IC) {
out.AddFormatted(", argc = %d", code->arguments_count());
diff --git a/src/factory.cc b/src/factory.cc
index c33b715..46d4d37 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -922,25 +922,18 @@
Handle<Object> descriptors) {
v8::NeanderArray callbacks(descriptors);
int nof_callbacks = callbacks.length();
+ int descriptor_count = array->number_of_descriptors();
Handle<DescriptorArray> result =
- NewDescriptorArray(array->number_of_descriptors() + nof_callbacks);
-
- // Number of descriptors added to the result so far.
- int descriptor_count = 0;
+ NewDescriptorArray(descriptor_count + nof_callbacks);
// Ensure that marking will not progress and change color of objects.
DescriptorArray::WhitenessWitness witness(*result);
// Copy the descriptors from the array.
- for (int i = 0; i < array->number_of_descriptors(); i++) {
- if (!array->IsNullDescriptor(i)) {
- DescriptorArray::CopyFrom(result, descriptor_count++, array, i, witness);
- }
+ for (int i = 0; i < descriptor_count; i++) {
+ DescriptorArray::CopyFrom(result, i, array, i, witness);
}
- // Number of duplicates detected.
- int duplicates = 0;
-
// Fill in new callback descriptors. Process the callbacks from
// back to front so that the last callback with a given name takes
// precedence over previously added callbacks with that name.
@@ -956,18 +949,14 @@
CallbacksDescriptor desc(*key, *entry, entry->property_attributes());
result->Set(descriptor_count, &desc, witness);
descriptor_count++;
- } else {
- duplicates++;
}
}
// If duplicates were detected, allocate a result of the right size
// and transfer the elements.
- if (duplicates > 0) {
- int number_of_descriptors = result->number_of_descriptors() - duplicates;
- Handle<DescriptorArray> new_result =
- NewDescriptorArray(number_of_descriptors);
- for (int i = 0; i < number_of_descriptors; i++) {
+ if (descriptor_count < result->length()) {
+ Handle<DescriptorArray> new_result = NewDescriptorArray(descriptor_count);
+ for (int i = 0; i < descriptor_count; i++) {
DescriptorArray::CopyFrom(new_result, i, result, i, witness);
}
result = new_result;
diff --git a/src/heap.cc b/src/heap.cc
index d15d99d..7d655b4 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -320,48 +320,52 @@
void Heap::PrintShortHeapStatistics() {
if (!FLAG_trace_gc_verbose) return;
- PrintF("Memory allocator, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d\n",
- isolate_->memory_allocator()->Size(),
- isolate_->memory_allocator()->Available());
- PrintF("New space, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d\n",
- Heap::new_space_.Size(),
- new_space_.Available());
- PrintF("Old pointers, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d"
- ", waste: %8" V8_PTR_PREFIX "d\n",
- old_pointer_space_->Size(),
- old_pointer_space_->Available(),
- old_pointer_space_->Waste());
- PrintF("Old data space, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d"
- ", waste: %8" V8_PTR_PREFIX "d\n",
- old_data_space_->Size(),
- old_data_space_->Available(),
- old_data_space_->Waste());
- PrintF("Code space, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d"
- ", waste: %8" V8_PTR_PREFIX "d\n",
- code_space_->Size(),
- code_space_->Available(),
- code_space_->Waste());
- PrintF("Map space, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d"
- ", waste: %8" V8_PTR_PREFIX "d\n",
- map_space_->Size(),
- map_space_->Available(),
- map_space_->Waste());
- PrintF("Cell space, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d"
- ", waste: %8" V8_PTR_PREFIX "d\n",
- cell_space_->Size(),
- cell_space_->Available(),
- cell_space_->Waste());
- PrintF("Large object space, used: %8" V8_PTR_PREFIX "d"
- ", available: %8" V8_PTR_PREFIX "d\n",
- lo_space_->Size(),
- lo_space_->Available());
+ PrintF("Memory allocator, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB\n",
+ isolate_->memory_allocator()->Size() / KB,
+ isolate_->memory_allocator()->Available() / KB);
+ PrintF("New space, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ new_space_.Size() / KB,
+ new_space_.Available() / KB,
+ new_space_.CommittedMemory() / KB);
+ PrintF("Old pointers, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ old_pointer_space_->SizeOfObjects() / KB,
+ old_pointer_space_->Available() / KB,
+ old_pointer_space_->CommittedMemory() / KB);
+ PrintF("Old data space, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ old_data_space_->SizeOfObjects() / KB,
+ old_data_space_->Available() / KB,
+ old_data_space_->CommittedMemory() / KB);
+ PrintF("Code space, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ code_space_->SizeOfObjects() / KB,
+ code_space_->Available() / KB,
+ code_space_->CommittedMemory() / KB);
+ PrintF("Map space, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ map_space_->SizeOfObjects() / KB,
+ map_space_->Available() / KB,
+ map_space_->CommittedMemory() / KB);
+ PrintF("Cell space, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ cell_space_->SizeOfObjects() / KB,
+ cell_space_->Available() / KB,
+ cell_space_->CommittedMemory() / KB);
+ PrintF("Large object space, used: %6" V8_PTR_PREFIX "d KB"
+ ", available: %6" V8_PTR_PREFIX "d KB"
+ ", committed: %6" V8_PTR_PREFIX "d KB\n",
+ lo_space_->SizeOfObjects() / KB,
+ lo_space_->Available() / KB,
+ lo_space_->CommittedMemory() / KB);
}
@@ -440,6 +444,56 @@
symbol_table()->Capacity());
isolate_->counters()->number_of_symbols()->Set(
symbol_table()->NumberOfElements());
+
+ isolate_->counters()->new_space_bytes_available()->Set(
+ static_cast<int>(new_space()->Available()));
+ isolate_->counters()->new_space_bytes_committed()->Set(
+ static_cast<int>(new_space()->CommittedMemory()));
+ isolate_->counters()->new_space_bytes_used()->Set(
+ static_cast<int>(new_space()->SizeOfObjects()));
+
+ isolate_->counters()->old_pointer_space_bytes_available()->Set(
+ static_cast<int>(old_pointer_space()->Available()));
+ isolate_->counters()->old_pointer_space_bytes_committed()->Set(
+ static_cast<int>(old_pointer_space()->CommittedMemory()));
+ isolate_->counters()->old_pointer_space_bytes_used()->Set(
+ static_cast<int>(old_pointer_space()->SizeOfObjects()));
+
+ isolate_->counters()->old_data_space_bytes_available()->Set(
+ static_cast<int>(old_data_space()->Available()));
+ isolate_->counters()->old_data_space_bytes_committed()->Set(
+ static_cast<int>(old_data_space()->CommittedMemory()));
+ isolate_->counters()->old_data_space_bytes_used()->Set(
+ static_cast<int>(old_data_space()->SizeOfObjects()));
+
+ isolate_->counters()->code_space_bytes_available()->Set(
+ static_cast<int>(code_space()->Available()));
+ isolate_->counters()->code_space_bytes_committed()->Set(
+ static_cast<int>(code_space()->CommittedMemory()));
+ isolate_->counters()->code_space_bytes_used()->Set(
+ static_cast<int>(code_space()->SizeOfObjects()));
+
+ isolate_->counters()->map_space_bytes_available()->Set(
+ static_cast<int>(map_space()->Available()));
+ isolate_->counters()->map_space_bytes_committed()->Set(
+ static_cast<int>(map_space()->CommittedMemory()));
+ isolate_->counters()->map_space_bytes_used()->Set(
+ static_cast<int>(map_space()->SizeOfObjects()));
+
+ isolate_->counters()->cell_space_bytes_available()->Set(
+ static_cast<int>(cell_space()->Available()));
+ isolate_->counters()->cell_space_bytes_committed()->Set(
+ static_cast<int>(cell_space()->CommittedMemory()));
+ isolate_->counters()->cell_space_bytes_used()->Set(
+ static_cast<int>(cell_space()->SizeOfObjects()));
+
+ isolate_->counters()->lo_space_bytes_available()->Set(
+ static_cast<int>(lo_space()->Available()));
+ isolate_->counters()->lo_space_bytes_committed()->Set(
+ static_cast<int>(lo_space()->CommittedMemory()));
+ isolate_->counters()->lo_space_bytes_used()->Set(
+ static_cast<int>(lo_space()->SizeOfObjects()));
+
#if defined(DEBUG)
ReportStatisticsAfterGC();
#endif // DEBUG
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 96357bd..1a9aea2 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -227,7 +227,7 @@
__ lea(edx,
Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset));
__ push(edx);
- __ SafePush(Immediate(Smi::FromInt(num_parameters)));
+ __ push(Immediate(Smi::FromInt(num_parameters)));
// Arguments to ArgumentsAccessStub:
// function, receiver address, parameter count.
// The stub will rewrite receiver and parameter count if the previous
@@ -2491,7 +2491,7 @@
SetSourcePosition(expr->position());
// Load function and argument count into edi and eax.
- __ SafeSet(eax, Immediate(arg_count));
+ __ Set(eax, Immediate(arg_count));
__ mov(edi, Operand(esp, arg_count * kPointerSize));
// Record call targets in unoptimized code, but not in the snapshot.
@@ -2849,7 +2849,7 @@
// parameter count in eax.
VisitForAccumulatorValue(args->at(0));
__ mov(edx, eax);
- __ SafeSet(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters())));
+ __ Set(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters())));
ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
__ CallStub(&stub);
context()->Plug(eax);
@@ -2861,7 +2861,7 @@
Label exit;
// Get the number of formal parameters.
- __ SafeSet(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters())));
+ __ Set(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters())));
// Check if the calling frame is an arguments adaptor frame.
__ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index a091ff1..52d8fa1 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -943,7 +943,7 @@
Code::Flags flags = Code::ComputeFlags(kind,
MONOMORPHIC,
extra_state,
- NORMAL,
+ Code::NORMAL,
argc);
Isolate* isolate = masm->isolate();
isolate->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, eax);
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 5225763..e27a326 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -3169,8 +3169,7 @@
__ cmp(output_reg, 0x80000000u);
DeoptimizeIf(equal, instr->environment());
} else {
- Label negative_sign;
- Label done;
+ Label negative_sign, done;
// Deoptimize on unordered.
__ xorps(xmm_scratch, xmm_scratch); // Zero the register.
__ ucomisd(input_reg, xmm_scratch);
@@ -3196,9 +3195,9 @@
DeoptimizeIf(equal, instr->environment());
__ jmp(&done, Label::kNear);
- // Non-zero negative reaches here
+ // Non-zero negative reaches here.
__ bind(&negative_sign);
- // Truncate, then compare and compensate
+ // Truncate, then compare and compensate.
__ cvttsd2si(output_reg, Operand(input_reg));
__ cvtsi2sd(xmm_scratch, output_reg);
__ ucomisd(input_reg, xmm_scratch);
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 6ab5bf3..78a5b68 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -1415,7 +1415,7 @@
GenerateMissBranch();
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -1962,7 +1962,7 @@
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2092,7 +2092,7 @@
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2197,7 +2197,7 @@
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2444,7 +2444,7 @@
GenerateMissBranch();
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2505,7 +2505,7 @@
GenerateMissBranch();
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2536,7 +2536,9 @@
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
@@ -2583,7 +2585,7 @@
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2629,7 +2631,7 @@
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2675,7 +2677,7 @@
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2723,7 +2725,7 @@
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2762,7 +2764,9 @@
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
@@ -2785,7 +2789,7 @@
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -2820,7 +2824,7 @@
__ jmp(miss_ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
@@ -2860,7 +2864,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NONEXISTENT, factory()->empty_string());
+ return GetCode(Code::NONEXISTENT, factory()->empty_string());
}
@@ -2880,7 +2884,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -2902,7 +2906,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2940,7 +2944,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2960,7 +2964,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -2986,7 +2990,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -3034,7 +3038,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -3063,7 +3067,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -3094,7 +3098,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3124,7 +3128,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -3155,7 +3159,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -3181,7 +3185,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3207,7 +3211,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3233,7 +3237,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3253,7 +3257,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -3280,7 +3284,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
diff --git a/src/ic.cc b/src/ic.cc
index bebdcee..1f0070b 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -1298,7 +1298,7 @@
static bool StoreICableLookup(LookupResult* lookup) {
// Bail out if we didn't find a result.
- if (!lookup->IsFound() || lookup->type() == NULL_DESCRIPTOR) return false;
+ if (!lookup->IsFound()) return false;
// Bail out if inline caching is not allowed.
if (!lookup->IsCacheable()) return false;
@@ -1385,12 +1385,13 @@
}
// Lookup the property locally in the receiver.
- if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
+ if (!receiver->IsJSGlobalProxy()) {
LookupResult lookup(isolate());
if (LookupForWrite(receiver, name, &lookup)) {
- // Generate a stub for this store.
- UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
+ if (FLAG_use_ic) { // Generate a stub for this store.
+ UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
+ }
} else {
// Strict mode doesn't allow setting non-existent global property
// or an assignment to a read only property.
@@ -1434,10 +1435,10 @@
Handle<Object> value) {
ASSERT(!receiver->IsJSGlobalProxy());
ASSERT(StoreICableLookup(lookup));
+ ASSERT(lookup->IsFound());
+
// These are not cacheable, so we never see such LookupResults here.
ASSERT(!lookup->IsHandler());
- // We get only called for properties or transitions, see StoreICableLookup.
- ASSERT(lookup->type() != NULL_DESCRIPTOR);
// If the property has a non-field type allowing map transitions
// where there is extra room in the object, we leave the IC in its
@@ -1509,8 +1510,8 @@
case CONSTANT_FUNCTION:
case CONSTANT_TRANSITION:
return;
+ case NONEXISTENT:
case HANDLER:
- case NULL_DESCRIPTOR:
UNREACHABLE();
return;
}
@@ -1583,7 +1584,7 @@
// Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
// via megamorphic stubs, since they don't have a map in their relocation info
// and so the stubs can't be harvested for the object needed for a map check.
- if (target()->type() != NORMAL) {
+ if (target()->type() != Code::NORMAL) {
TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type");
return generic_stub;
}
@@ -1936,10 +1937,10 @@
Handle<Object> value) {
ASSERT(!receiver->IsJSGlobalProxy());
ASSERT(StoreICableLookup(lookup));
+ ASSERT(lookup->IsFound());
+
// These are not cacheable, so we never see such LookupResults here.
ASSERT(!lookup->IsHandler());
- // We get only called for properties or transitions, see StoreICableLookup.
- ASSERT(lookup->type() != NULL_DESCRIPTOR);
// If the property has a non-field type allowing map transitions
// where there is extra room in the object, we leave the IC in its
@@ -1978,7 +1979,7 @@
: generic_stub();
break;
case HANDLER:
- case NULL_DESCRIPTOR:
+ case NONEXISTENT:
UNREACHABLE();
return;
}
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index f26d9a5..d0b4ae4 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -1901,8 +1901,7 @@
}
// If the descriptor contains a transition (value is a Map), we don't mark the
- // value as live. It might be set to the NULL_DESCRIPTOR in
- // ClearNonLiveTransitions later.
+ // value as live. It might be removed by ClearNonLiveTransitions later.
for (int i = 0; i < descriptors->number_of_descriptors(); ++i) {
Object** key_slot = descriptors->GetKeySlot(i);
Object* key = *key_slot;
@@ -1940,7 +1939,9 @@
break;
case MAP_TRANSITION:
case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
+ break;
+ case NONEXISTENT:
+ UNREACHABLE();
break;
}
}
diff --git a/src/mips/ic-mips.cc b/src/mips/ic-mips.cc
index 5d530d0..3f2ecb8 100644
--- a/src/mips/ic-mips.cc
+++ b/src/mips/ic-mips.cc
@@ -398,7 +398,7 @@
Code::Flags flags = Code::ComputeFlags(kind,
MONOMORPHIC,
extra_state,
- NORMAL,
+ Code::NORMAL,
argc);
Isolate::Current()->stub_cache()->GenerateProbe(
masm, flags, a1, a2, a3, t0, t1, t2);
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index 1cfa2bb..d4d4de0 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -1531,7 +1531,7 @@
GenerateMissBranch();
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -2078,7 +2078,7 @@
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2212,7 +2212,7 @@
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2313,7 +2313,7 @@
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2534,7 +2534,7 @@
GenerateMissBranch();
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2593,7 +2593,7 @@
GenerateMissBranch();
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2623,7 +2623,9 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
@@ -2668,7 +2670,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2714,7 +2716,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2759,7 +2761,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2804,7 +2806,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2838,7 +2840,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NONEXISTENT, factory()->empty_string());
+ return GetCode(Code::NONEXISTENT, factory()->empty_string());
}
@@ -2860,7 +2862,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -2881,7 +2883,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2919,7 +2921,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2939,7 +2941,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -2962,7 +2964,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -3003,7 +3005,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -3025,7 +3027,7 @@
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -3049,7 +3051,7 @@
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3073,7 +3075,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -3098,7 +3100,7 @@
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -3118,7 +3120,7 @@
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3143,7 +3145,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3167,7 +3169,7 @@
__ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3187,7 +3189,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -3214,7 +3216,7 @@
__ Jump(miss_ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
@@ -3253,7 +3255,9 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
@@ -3277,7 +3281,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -3315,7 +3319,7 @@
__ Jump(miss_ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index cefa3f8..74c015b 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -953,7 +953,9 @@
case CONSTANT_FUNCTION:
case HANDLER:
case INTERCEPTOR:
- case NULL_DESCRIPTOR:
+ break;
+ case NONEXISTENT:
+ UNREACHABLE();
break;
}
}
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 2cdfad6..b334669 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1863,7 +1863,7 @@
void FixedArray::set_null_unchecked(Heap* heap, int index) {
ASSERT(index >= 0 && index < this->length());
- ASSERT(!HEAP->InNewSpace(heap->null_value()));
+ ASSERT(!heap->InNewSpace(heap->null_value()));
WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
}
@@ -1976,6 +1976,17 @@
}
+void DescriptorArray::SetKeyUnchecked(Heap* heap,
+ int descriptor_number,
+ String* key) {
+ ASSERT(descriptor_number < number_of_descriptors());
+ set_unchecked(heap,
+ ToKeyIndex(descriptor_number),
+ key,
+ UPDATE_WRITE_BARRIER);
+}
+
+
Object** DescriptorArray::GetValueSlot(int descriptor_number) {
ASSERT(descriptor_number < number_of_descriptors());
return HeapObject::RawField(
@@ -1990,12 +2001,24 @@
}
-void DescriptorArray::SetNullValueUnchecked(int descriptor_number, Heap* heap) {
+void DescriptorArray::SetNullValueUnchecked(Heap* heap, int descriptor_number) {
ASSERT(descriptor_number < number_of_descriptors());
set_null_unchecked(heap, ToValueIndex(descriptor_number));
}
+
+void DescriptorArray::SetValueUnchecked(Heap* heap,
+ int descriptor_number,
+ Object* value) {
+ ASSERT(descriptor_number < number_of_descriptors());
+ set_unchecked(heap,
+ ToValueIndex(descriptor_number),
+ value,
+ UPDATE_WRITE_BARRIER);
+}
+
+
PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
ASSERT(descriptor_number < number_of_descriptors());
Object* details = get(ToDetailsIndex(descriptor_number));
@@ -2059,19 +2082,16 @@
case CONSTANT_FUNCTION:
case HANDLER:
case INTERCEPTOR:
- case NULL_DESCRIPTOR:
return false;
+ case NONEXISTENT:
+ UNREACHABLE();
+ break;
}
UNREACHABLE(); // Keep the compiler happy.
return false;
}
-bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
- return GetType(descriptor_number) == NULL_DESCRIPTOR;
-}
-
-
void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
desc->Init(GetKey(descriptor_number),
GetValue(descriptor_number),
@@ -3029,7 +3049,7 @@
}
-PropertyType Code::type() {
+Code::StubType Code::type() {
return ExtractTypeFromFlags(flags());
}
@@ -3301,7 +3321,7 @@
Code::Flags Code::ComputeFlags(Kind kind,
InlineCacheState ic_state,
ExtraICState extra_ic_state,
- PropertyType type,
+ StubType type,
int argc,
InlineCacheHolderFlag holder) {
// Extra IC state is only allowed for call IC stubs or for store IC
@@ -3322,7 +3342,7 @@
Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
- PropertyType type,
+ StubType type,
ExtraICState extra_ic_state,
InlineCacheHolderFlag holder,
int argc) {
@@ -3345,7 +3365,7 @@
}
-PropertyType Code::ExtractTypeFromFlags(Flags flags) {
+Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
return TypeField::decode(flags);
}
@@ -3464,10 +3484,23 @@
}
+void Map::ClearDescriptorArray() {
+ int bitfield3 = bit_field3();
+#ifdef DEBUG
+ Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
+ if (!object->IsSmi()) {
+ ZapInstanceDescriptors();
+ }
+#endif
+ WRITE_FIELD(this,
+ kInstanceDescriptorsOrBitField3Offset,
+ Smi::FromInt(bitfield3));
+}
+
+
void Map::set_bit_field3(int value) {
ASSERT(Smi::IsValid(value));
- Object* object = READ_FIELD(this,
- kInstanceDescriptorsOrBitField3Offset);
+ Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
if (object->IsSmi()) {
WRITE_FIELD(this,
kInstanceDescriptorsOrBitField3Offset,
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index 6714cdc..ac3765e 100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -279,12 +279,10 @@
case CONSTANT_TRANSITION:
PrintF(out, "(constant transition)\n");
break;
- case NULL_DESCRIPTOR:
- PrintF(out, "(null descriptor)\n");
- break;
case NORMAL: // only in slow mode
case HANDLER: // only in lookup results, not in descriptors
case INTERCEPTOR: // only in lookup results, not in descriptors
+ case NONEXISTENT:
UNREACHABLE();
break;
}
diff --git a/src/objects.cc b/src/objects.cc
index 78f83c4..5748317 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -643,7 +643,9 @@
}
case MAP_TRANSITION:
case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
+ break;
+ case NONEXISTENT:
+ UNREACHABLE();
break;
}
UNREACHABLE();
@@ -2156,7 +2158,9 @@
}
case MAP_TRANSITION:
case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
+ break;
+ case NONEXISTENT:
+ UNREACHABLE();
break;
}
}
@@ -2939,9 +2943,8 @@
// FIELD, even if the value is a constant function.
return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
}
- case NULL_DESCRIPTOR:
- return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
case HANDLER:
+ case NONEXISTENT:
UNREACHABLE();
return value;
}
@@ -3037,9 +3040,9 @@
case CONSTANT_TRANSITION:
// Replace with a MAP_TRANSITION to a new map with a FIELD, even
// if the value is a function.
- case NULL_DESCRIPTOR:
return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
case HANDLER:
+ case NONEXISTENT:
UNREACHABLE();
}
UNREACHABLE(); // keep the compiler happy
@@ -3332,11 +3335,11 @@
}
case MAP_TRANSITION:
case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
case INTERCEPTOR:
break;
case HANDLER:
case NORMAL:
+ case NONEXISTENT:
UNREACHABLE();
break;
}
@@ -3680,8 +3683,7 @@
this->FastPropertyAt(descriptors->GetFieldIndex(0));
return StringDictionary::cast(hidden_store);
} else {
- ASSERT(descriptors->GetType(0) == NULL_DESCRIPTOR ||
- descriptors->GetType(0) == MAP_TRANSITION);
+ ASSERT(descriptors->GetType(0) == MAP_TRANSITION);
}
}
} else {
@@ -3729,8 +3731,7 @@
this->FastPropertyAtPut(descriptors->GetFieldIndex(0), dictionary);
return this;
} else {
- ASSERT(descriptors->GetType(0) == NULL_DESCRIPTOR ||
- descriptors->GetType(0) == MAP_TRANSITION);
+ ASSERT(descriptors->GetType(0) == MAP_TRANSITION);
}
}
}
@@ -4177,9 +4178,7 @@
int Map::PropertyIndexFor(String* name) {
DescriptorArray* descs = instance_descriptors();
for (int i = 0; i < descs->number_of_descriptors(); i++) {
- if (name->Equals(descs->GetKey(i)) && !descs->IsNullDescriptor(i)) {
- return descs->GetFieldIndex(i);
- }
+ if (name->Equals(descs->GetKey(i))) return descs->GetFieldIndex(i);
}
return -1;
}
@@ -5086,11 +5085,13 @@
case CONSTANT_FUNCTION:
case HANDLER:
case INTERCEPTOR:
- case NULL_DESCRIPTOR:
// We definitely have no map transition.
raw_index += 2;
++index;
break;
+ case NONEXISTENT:
+ UNREACHABLE();
+ break;
}
}
if (index == descriptor_array_->number_of_descriptors()) {
@@ -5274,7 +5275,7 @@
// The number of monomorphic stubs for normal load/store/call IC's can grow to
// a large number and therefore they need to go into a hash table. They are
// used to load global properties from cells.
- if (code->type() == NORMAL) {
+ if (code->type() == Code::NORMAL) {
// Make sure that a hash table is allocated for the normal load code cache.
if (normal_type_cache()->IsUndefined()) {
Object* result;
@@ -5365,7 +5366,7 @@
Object* CodeCache::Lookup(String* name, Code::Flags flags) {
- if (Code::ExtractTypeFromFlags(flags) == NORMAL) {
+ if (Code::ExtractTypeFromFlags(flags) == Code::NORMAL) {
return LookupNormalTypeCache(name, flags);
} else {
return LookupDefaultCache(name, flags);
@@ -5403,7 +5404,7 @@
int CodeCache::GetIndex(Object* name, Code* code) {
- if (code->type() == NORMAL) {
+ if (code->type() == Code::NORMAL) {
if (normal_type_cache()->IsUndefined()) return -1;
CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache());
return cache->GetIndex(String::cast(name), code->flags());
@@ -5419,7 +5420,7 @@
void CodeCache::RemoveByIndex(Object* name, Code* code, int index) {
- if (code->type() == NORMAL) {
+ if (code->type() == Code::NORMAL) {
ASSERT(!normal_type_cache()->IsUndefined());
CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache());
ASSERT(cache->GetIndex(String::cast(name), code->flags()) == index);
@@ -5880,7 +5881,6 @@
// removing all other transitions is not supported.
bool remove_transitions = transition_flag == REMOVE_TRANSITIONS;
ASSERT(remove_transitions == !descriptor->ContainsTransition());
- ASSERT(descriptor->GetDetails().type() != NULL_DESCRIPTOR);
// Ensure the key is a symbol.
{ MaybeObject* maybe_result = descriptor->KeyToSymbol();
@@ -5889,7 +5889,6 @@
int new_size = 0;
for (int i = 0; i < number_of_descriptors(); i++) {
- if (IsNullDescriptor(i)) continue;
if (remove_transitions && IsTransitionOnly(i)) continue;
new_size++;
}
@@ -5947,8 +5946,7 @@
insertion_index = to_index++;
if (replacing) from_index++;
} else {
- if (!(IsNullDescriptor(from_index) ||
- (remove_transitions && IsTransitionOnly(from_index)))) {
+ if (!(remove_transitions && IsTransitionOnly(from_index))) {
MaybeObject* copy_result =
new_descriptors->CopyFrom(to_index++, this, from_index, witness);
if (copy_result->IsFailure()) return copy_result;
@@ -6078,8 +6076,7 @@
}
for (; low <= limit && GetKey(low)->Hash() == hash; ++low) {
- if (GetKey(low)->Equals(name) && !IsNullDescriptor(low))
- return low;
+ if (GetKey(low)->Equals(name)) return low;
}
return kNotFound;
@@ -6091,9 +6088,7 @@
for (int number = 0; number < len; number++) {
String* entry = GetKey(number);
if (mode == EXPECT_SORTED && entry->Hash() > hash) break;
- if (name->Equals(entry) && !IsNullDescriptor(number)) {
- return number;
- }
+ if (name->Equals(entry)) return number;
}
return kNotFound;
}
@@ -7352,74 +7347,158 @@
}
+// This function should only be called from within the GC, since it uses
+// IncrementLiveBytesFromGC. If called from anywhere else, this results in an
+// inconsistent live-bytes count.
+static void RightTrimFixedArray(Heap* heap, FixedArray* elms, int to_trim) {
+ ASSERT(elms->map() != HEAP->fixed_cow_array_map());
+ // For now this trick is only applied to fixed arrays in new and paged space.
+ // In large object space the object's start must coincide with chunk
+ // and thus the trick is just not applicable.
+ ASSERT(!HEAP->lo_space()->Contains(elms));
+
+ const int len = elms->length();
+
+ ASSERT(to_trim < len);
+
+ Address new_end = elms->address() + FixedArray::SizeFor(len - to_trim);
+
+#ifdef DEBUG
+ // If we are doing a big trim in old space then we zap the space.
+ Object** zap = reinterpret_cast<Object**>(new_end);
+ for (int i = 1; i < to_trim; i++) {
+ *zap++ = Smi::FromInt(0);
+ }
+#endif
+
+ int size_delta = to_trim * kPointerSize;
+
+ // Technically in new space this write might be omitted (except for
+ // debug mode which iterates through the heap), but to play safer
+ // we still do it.
+ heap->CreateFillerObjectAt(new_end, size_delta);
+
+ elms->set_length(len - to_trim);
+
+ // Maintain marking consistency for IncrementalMarking.
+ if (Marking::IsBlack(Marking::MarkBitFrom(elms))) {
+ MemoryChunk::IncrementLiveBytesFromGC(elms->address(), -size_delta);
+ }
+}
+
+
+// If the descriptor describes a transition to a dead map, the back pointer
+// of this map is cleared and we return true. Otherwise we return false.
+static bool ClearNonLiveTransitionsFromDescriptor(Heap* heap,
+ DescriptorArray* d,
+ int descriptor_index) {
+ // If the pair (value, details) is a map transition, check if the target is
+ // live. If not, null the descriptor. Also drop the back pointer for that
+ // map transition, so that this map is not reached again by following a back
+ // pointer from that non-live map.
+ PropertyDetails details(d->GetDetails(descriptor_index));
+ switch (details.type()) {
+ case MAP_TRANSITION:
+ case CONSTANT_TRANSITION:
+ return ClearBackPointer(heap, d->GetValue(descriptor_index));
+ case CALLBACKS: {
+ Object* object = d->GetValue(descriptor_index);
+ if (object->IsAccessorPair()) {
+ bool cleared = true;
+ AccessorPair* accessors = AccessorPair::cast(object);
+ Object* getter = accessors->getter();
+ if (getter->IsMap()) {
+ if (ClearBackPointer(heap, getter)) {
+ accessors->set_getter(heap->the_hole_value());
+ } else {
+ cleared = false;
+ }
+ } else if (!getter->IsTheHole()) {
+ cleared = false;
+ }
+ Object* setter = accessors->setter();
+ if (setter->IsMap()) {
+ if (ClearBackPointer(heap, setter)) {
+ accessors->set_setter(heap->the_hole_value());
+ } else {
+ cleared = false;
+ }
+ } else if (!setter->IsTheHole()) {
+ cleared = false;
+ }
+ return cleared;
+ }
+ return false;
+ }
+ case NORMAL:
+ case FIELD:
+ case CONSTANT_FUNCTION:
+ case HANDLER:
+ case INTERCEPTOR:
+ return false;
+ case NONEXISTENT:
+ break;
+ }
+ UNREACHABLE();
+ return true;
+}
+
+
+// TODO(mstarzinger): This method should be moved into MarkCompactCollector,
+// because it cannot be called from outside the GC and we already have methods
+// depending on the transitions layout in the GC anyways.
void Map::ClearNonLiveTransitions(Heap* heap) {
- DescriptorArray* d = DescriptorArray::cast(
- *RawField(this, Map::kInstanceDescriptorsOrBitField3Offset));
- if (d->IsEmpty()) return;
+ Object* array = *RawField(this, Map::kInstanceDescriptorsOrBitField3Offset);
+ // If there are no descriptors to be cleared, return.
+ // TODO(verwaest) Should be an assert, otherwise back pointers are not
+ // properly cleared.
+ if (array->IsSmi()) return;
+ DescriptorArray* d = DescriptorArray::cast(array);
+
+ int descriptor_index = 0;
+ // Compact all live descriptors to the left.
+ for (int i = 0; i < d->number_of_descriptors(); ++i) {
+ if (!ClearNonLiveTransitionsFromDescriptor(heap, d, i)) {
+ if (i != descriptor_index) {
+ String* key = d->GetKey(i);
+ Object* value = d->GetValue(i);
+ d->SetKeyUnchecked(heap, descriptor_index, key);
+ d->SetDetailsUnchecked(descriptor_index, d->GetDetails(i).AsSmi());
+ d->SetValueUnchecked(heap, descriptor_index, value);
+ MarkCompactCollector* collector = heap->mark_compact_collector();
+ Object** key_slot = d->GetKeySlot(descriptor_index);
+ collector->RecordSlot(key_slot, key_slot, key);
+ if (value->IsHeapObject()) {
+ Object** value_slot = d->GetValueSlot(descriptor_index);
+ collector->RecordSlot(value_slot, value_slot, value);
+ }
+ }
+ descriptor_index++;
+ }
+ }
+
Map* elements_transition = d->elements_transition_map();
if (elements_transition != NULL &&
ClearBackPointer(heap, elements_transition)) {
+ elements_transition = NULL;
d->ClearElementsTransition();
+ } else {
+ // If there are no descriptors to be cleared, return.
+ // TODO(verwaest) Should be an assert, otherwise back pointers are not
+ // properly cleared.
+ if (descriptor_index == d->number_of_descriptors()) return;
}
- Smi* NullDescriptorDetails =
- PropertyDetails(NONE, NULL_DESCRIPTOR).AsSmi();
- for (int i = 0; i < d->number_of_descriptors(); ++i) {
- // If the pair (value, details) is a map transition, check if the target is
- // live. If not, null the descriptor. Also drop the back pointer for that
- // map transition, so that this map is not reached again by following a back
- // pointer from that non-live map.
- bool keep_entry = false;
- PropertyDetails details(d->GetDetails(i));
- switch (details.type()) {
- case MAP_TRANSITION:
- case CONSTANT_TRANSITION:
- keep_entry = !ClearBackPointer(heap, d->GetValue(i));
- break;
- case CALLBACKS: {
- Object* object = d->GetValue(i);
- if (object->IsAccessorPair()) {
- AccessorPair* accessors = AccessorPair::cast(object);
- Object* getter = accessors->getter();
- if (getter->IsMap()) {
- if (ClearBackPointer(heap, getter)) {
- accessors->set_getter(heap->the_hole_value());
- } else {
- keep_entry = true;
- }
- } else if (!getter->IsTheHole()) {
- keep_entry = true;
- }
- Object* setter = accessors->setter();
- if (setter->IsMap()) {
- if (ClearBackPointer(heap, setter)) {
- accessors->set_setter(heap->the_hole_value());
- } else {
- keep_entry = true;
- }
- } else if (!setter->IsTheHole()) {
- keep_entry = true;
- }
- } else {
- keep_entry = true;
- }
- break;
- }
- case NORMAL:
- case FIELD:
- case CONSTANT_FUNCTION:
- case HANDLER:
- case INTERCEPTOR:
- case NULL_DESCRIPTOR:
- keep_entry = true;
- break;
- }
- // Make sure that an entry containing only dead transitions gets collected.
- // What we *really* want to do here is removing this entry completely, but
- // for technical reasons we can't do this, so we zero it out instead.
- if (!keep_entry) {
- d->SetDetailsUnchecked(i, NullDescriptorDetails);
- d->SetNullValueUnchecked(i, heap);
- }
+
+ // If the final descriptor array does not contain any live descriptors, remove
+ // the descriptor array from the map.
+ if (descriptor_index == 0 && elements_transition == NULL) {
+ ClearDescriptorArray();
+ return;
+ }
+
+ int trim = d->number_of_descriptors() - descriptor_index;
+ if (trim > 0) {
+ RightTrimFixedArray(heap, d, trim * DescriptorArray::kDescriptorSize);
}
}
@@ -8554,17 +8633,15 @@
}
-const char* Code::PropertyType2String(PropertyType type) {
+const char* Code::StubType2String(StubType type) {
switch (type) {
case NORMAL: return "NORMAL";
case FIELD: return "FIELD";
case CONSTANT_FUNCTION: return "CONSTANT_FUNCTION";
case CALLBACKS: return "CALLBACKS";
- case HANDLER: return "HANDLER";
case INTERCEPTOR: return "INTERCEPTOR";
case MAP_TRANSITION: return "MAP_TRANSITION";
- case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION";
- case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR";
+ case NONEXISTENT: return "NONEXISTENT";
}
UNREACHABLE(); // keep the compiler happy
return NULL;
@@ -8602,7 +8679,7 @@
PrintF(out, "ic_state = %s\n", ICState2String(ic_state()));
PrintExtraICState(out, kind(), extra_ic_state());
if (ic_state() == MONOMORPHIC) {
- PrintF(out, "type = %s\n", PropertyType2String(type()));
+ PrintF(out, "type = %s\n", StubType2String(type()));
}
if (is_call_stub() || is_keyed_call_stub()) {
PrintF(out, "argc = %d\n", arguments_count());
@@ -11263,8 +11340,10 @@
case CONSTANT_FUNCTION:
case HANDLER:
case INTERCEPTOR:
- case NULL_DESCRIPTOR:
return false;
+ case NONEXISTENT:
+ UNREACHABLE();
+ break;
}
UNREACHABLE(); // Keep the compiler happy.
return false;
@@ -12864,11 +12943,11 @@
// If the object does not have an identity hash, it was never used as a key.
{ MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
if (maybe_hash->ToObjectUnchecked()->IsUndefined()) {
- return GetHeap()->undefined_value();
+ return GetHeap()->the_hole_value();
}
}
int entry = FindEntry(key);
- if (entry == kNotFound) return GetHeap()->undefined_value();
+ if (entry == kNotFound) return GetHeap()->the_hole_value();
return get(EntryToIndex(entry) + 1);
}
@@ -12885,7 +12964,7 @@
int entry = FindEntry(key);
// Check whether to perform removal operation.
- if (value->IsUndefined()) {
+ if (value->IsTheHole()) {
if (entry == kNotFound) return this;
RemoveEntry(entry);
return Shrink(key);
diff --git a/src/objects.h b/src/objects.h
index 9c3d0f8..90564f3 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -2501,9 +2501,13 @@
// Accessors for fetching instance descriptor at descriptor number.
inline String* GetKey(int descriptor_number);
inline Object** GetKeySlot(int descriptor_number);
+ inline void SetKeyUnchecked(Heap* heap, int descriptor_number, String* value);
inline Object* GetValue(int descriptor_number);
inline Object** GetValueSlot(int descriptor_number);
- inline void SetNullValueUnchecked(int descriptor_number, Heap* heap);
+ inline void SetNullValueUnchecked(Heap* heap, int descriptor_number);
+ inline void SetValueUnchecked(Heap* heap,
+ int descriptor_number,
+ Object* value);
inline PropertyDetails GetDetails(int descriptor_number);
inline void SetDetailsUnchecked(int descriptor_number, Smi* value);
inline PropertyType GetType(int descriptor_number);
@@ -2513,7 +2517,6 @@
inline AccessorDescriptor* GetCallbacks(int descriptor_number);
inline bool IsProperty(int descriptor_number);
inline bool IsTransitionOnly(int descriptor_number);
- inline bool IsNullDescriptor(int descriptor_number);
// WhitenessWitness is used to prove that a specific descriptor array is white
// (unmarked), so incremental write barriers can be skipped because the
@@ -3322,12 +3325,12 @@
return reinterpret_cast<ObjectHashTable*>(obj);
}
- // Looks up the value associated with the given key. The undefined value is
+ // Looks up the value associated with the given key. The hole value is
// returned in case the key is not present.
Object* Lookup(Object* key);
// Adds (or overwrites) the value associated with the given key. Mapping a
- // key to the undefined value causes removal of the whole entry.
+ // key to the hole value causes removal of the whole entry.
MUST_USE_RESULT MaybeObject* Put(Object* key, Object* value);
private:
@@ -4199,6 +4202,17 @@
LAST_IC_KIND = TO_BOOLEAN_IC
};
+ // Types of stubs.
+ enum StubType {
+ NORMAL,
+ FIELD,
+ CONSTANT_FUNCTION,
+ CALLBACKS,
+ INTERCEPTOR,
+ MAP_TRANSITION,
+ NONEXISTENT
+ };
+
enum {
NUMBER_OF_KINDS = LAST_IC_KIND + 1
};
@@ -4211,7 +4225,7 @@
// Printing
static const char* Kind2String(Kind kind);
static const char* ICState2String(InlineCacheState state);
- static const char* PropertyType2String(PropertyType type);
+ static const char* StubType2String(StubType type);
static void PrintExtraICState(FILE* out, Kind kind, ExtraICState extra);
inline void Disassemble(const char* name) {
Disassemble(name, stdout);
@@ -4261,7 +4275,7 @@
inline Kind kind();
inline InlineCacheState ic_state(); // Only valid for IC stubs.
inline ExtraICState extra_ic_state(); // Only valid for IC stubs.
- inline PropertyType type(); // Only valid for monomorphic IC stubs.
+ inline StubType type(); // Only valid for monomorphic IC stubs.
inline int arguments_count(); // Only valid for call IC stubs.
// Testers for IC stub kinds.
@@ -4404,19 +4418,19 @@
Kind kind,
InlineCacheState ic_state = UNINITIALIZED,
ExtraICState extra_ic_state = kNoExtraICState,
- PropertyType type = NORMAL,
+ StubType type = NORMAL,
int argc = -1,
InlineCacheHolderFlag holder = OWN_MAP);
static inline Flags ComputeMonomorphicFlags(
Kind kind,
- PropertyType type,
+ StubType type,
ExtraICState extra_ic_state = kNoExtraICState,
InlineCacheHolderFlag holder = OWN_MAP,
int argc = -1);
static inline InlineCacheState ExtractICStateFromFlags(Flags flags);
- static inline PropertyType ExtractTypeFromFlags(Flags flags);
+ static inline StubType ExtractTypeFromFlags(Flags flags);
static inline Kind ExtractKindFromFlags(Flags flags);
static inline InlineCacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags);
@@ -4552,14 +4566,14 @@
// Flags layout. BitField<type, shift, size>.
class ICStateField: public BitField<InlineCacheState, 0, 3> {};
- class TypeField: public BitField<PropertyType, 3, 4> {};
- class CacheHolderField: public BitField<InlineCacheHolderFlag, 7, 1> {};
- class KindField: public BitField<Kind, 8, 4> {};
- class ExtraICStateField: public BitField<ExtraICState, 12, 2> {};
- class IsPregeneratedField: public BitField<bool, 14, 1> {};
+ class TypeField: public BitField<StubType, 3, 3> {};
+ class CacheHolderField: public BitField<InlineCacheHolderFlag, 6, 1> {};
+ class KindField: public BitField<Kind, 7, 4> {};
+ class ExtraICStateField: public BitField<ExtraICState, 11, 2> {};
+ class IsPregeneratedField: public BitField<bool, 13, 1> {};
// Signed field cannot be encoded using the BitField class.
- static const int kArgumentsCountShift = 15;
+ static const int kArgumentsCountShift = 14;
static const int kArgumentsCountMask = ~((1 << kArgumentsCountShift) - 1);
// This constant should be encodable in an ARM instruction.
@@ -4769,6 +4783,10 @@
// [instance descriptors]: describes the object.
DECL_ACCESSORS(instance_descriptors, DescriptorArray)
+ // Should only be called to clear a descriptor array that was only used to
+ // store transitions and does not contain any live transitions anymore.
+ inline void ClearDescriptorArray();
+
// Sets the instance descriptor array for the map to be an empty descriptor
// array.
inline void clear_instance_descriptors();
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index a3143be..217046f 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -2220,7 +2220,9 @@
case INTERCEPTOR: // only in lookup results, not in descriptors
case MAP_TRANSITION: // we do not care about transitions here...
case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR: // ... and not about "holes"
+ break;
+ case NONEXISTENT:
+ UNREACHABLE();
break;
}
}
diff --git a/src/property-details.h b/src/property-details.h
index a623fe9..e898a7d 100644
--- a/src/property-details.h
+++ b/src/property-details.h
@@ -64,11 +64,8 @@
// All properties before MAP_TRANSITION are real.
MAP_TRANSITION = 6, // only in fast mode
CONSTANT_TRANSITION = 7, // only in fast mode
- NULL_DESCRIPTOR = 8, // only in fast mode
- // There are no IC stubs for NULL_DESCRIPTORS. Therefore,
- // NULL_DESCRIPTOR can be used as the type flag for IC stubs for
- // nonexistent properties.
- NONEXISTENT = NULL_DESCRIPTOR
+ // Only used as a marker in LookupResult.
+ NONEXISTENT = 8
};
diff --git a/src/property.cc b/src/property.cc
index 8c69541..3258b8c 100644
--- a/src/property.cc
+++ b/src/property.cc
@@ -89,8 +89,8 @@
GetTransitionMap()->Print(out);
PrintF(out, "\n");
break;
- case NULL_DESCRIPTOR:
- PrintF(out, " =type = null descriptor\n");
+ case NONEXISTENT:
+ UNREACHABLE();
break;
}
}
@@ -123,8 +123,10 @@
case CONSTANT_FUNCTION:
case HANDLER:
case INTERCEPTOR:
- case NULL_DESCRIPTOR:
return false;
+ case NONEXISTENT:
+ UNREACHABLE();
+ break;
}
UNREACHABLE(); // Keep the compiler happy.
return false;
diff --git a/src/property.h b/src/property.h
index 55c72ba..76ae0fb 100644
--- a/src/property.h
+++ b/src/property.h
@@ -173,8 +173,10 @@
}
case MAP_TRANSITION:
case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
return false;
+ case NONEXISTENT:
+ UNREACHABLE();
+ break;
}
UNREACHABLE(); // keep the compiler happy
return false;
diff --git a/src/runtime.cc b/src/runtime.cc
index 82206dd..74f3e43 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -795,8 +795,35 @@
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
- Handle<Object> key(args[1]);
- return ObjectHashTable::cast(holder->table())->Lookup(*key);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+ Handle<Object> lookup(table->Lookup(*key));
+ return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_MapHas) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+ Handle<Object> lookup(table->Lookup(*key));
+ return isolate->heap()->ToBoolean(!lookup->IsTheHole());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_MapDelete) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+ Handle<Object> lookup(table->Lookup(*key));
+ Handle<ObjectHashTable> new_table =
+ PutIntoObjectHashTable(table, key, isolate->factory()->the_hole_value());
+ holder->set_table(*new_table);
+ return isolate->heap()->ToBoolean(!lookup->IsTheHole());
}
@@ -804,8 +831,8 @@
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
- Handle<Object> key(args[1]);
- Handle<Object> value(args[2]);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
holder->set_table(*new_table);
@@ -826,11 +853,38 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapGet) {
- NoHandleAllocation ha;
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, key, 1);
- return ObjectHashTable::cast(weakmap->table())->Lookup(*key);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
+ Handle<Object> lookup(table->Lookup(*key));
+ return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapHas) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, key, 1);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
+ Handle<Object> lookup(table->Lookup(*key));
+ return isolate->heap()->ToBoolean(!lookup->IsTheHole());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapDelete) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, key, 1);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
+ Handle<Object> lookup(table->Lookup(*key));
+ Handle<ObjectHashTable> new_table =
+ PutIntoObjectHashTable(table, key, isolate->factory()->the_hole_value());
+ weakmap->set_table(*new_table);
+ return isolate->heap()->ToBoolean(!lookup->IsTheHole());
}
@@ -10286,9 +10340,9 @@
case INTERCEPTOR:
case MAP_TRANSITION:
case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
return heap->undefined_value();
case HANDLER:
+ case NONEXISTENT:
UNREACHABLE();
return heap->undefined_value();
}
diff --git a/src/runtime.h b/src/runtime.h
index 9968b29..3430a58 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -302,11 +302,15 @@
/* Harmony maps */ \
F(MapInitialize, 1, 1) \
F(MapGet, 2, 1) \
+ F(MapHas, 2, 1) \
+ F(MapDelete, 2, 1) \
F(MapSet, 3, 1) \
\
/* Harmony weakmaps */ \
F(WeakMapInitialize, 1, 1) \
F(WeakMapGet, 2, 1) \
+ F(WeakMapHas, 2, 1) \
+ F(WeakMapDelete, 2, 1) \
F(WeakMapSet, 3, 1) \
\
/* Statements */ \
diff --git a/src/spaces.h b/src/spaces.h
index b0ecc5d..6602c89 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -2496,6 +2496,10 @@
return objects_size_;
}
+ intptr_t CommittedMemory() {
+ return Size();
+ }
+
int PageCount() {
return page_count_;
}
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index d790f03..c5ae175 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -119,7 +119,7 @@
// Compile the stub that is either shared for all names or
// name specific if there are global objects involved.
Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT);
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::NONEXISTENT);
Handle<Object> probe(receiver->map()->FindInCodeCache(*cache_name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -138,7 +138,7 @@
Handle<JSObject> holder,
int field_index) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD);
+ Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::FIELD);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -158,7 +158,8 @@
Handle<AccessorInfo> callback) {
ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -177,7 +178,8 @@
Handle<JSObject> holder,
Handle<JSFunction> getter) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CALLBACKS);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -197,7 +199,7 @@
Handle<JSFunction> value) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION);
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::CONSTANT_FUNCTION);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -215,7 +217,8 @@
Handle<JSObject> receiver,
Handle<JSObject> holder) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::INTERCEPTOR);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -240,7 +243,8 @@
Handle<JSGlobalPropertyCell> cell,
bool is_dont_delete) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::NORMAL);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -259,7 +263,8 @@
Handle<JSObject> holder,
int field_index) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::FIELD);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -278,8 +283,8 @@
Handle<JSObject> holder,
Handle<JSFunction> value) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
- Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION);
+ Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC,
+ Code::CONSTANT_FUNCTION);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -298,7 +303,7 @@
Handle<JSObject> holder) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR);
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -318,7 +323,7 @@
Handle<AccessorInfo> callback) {
ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -335,7 +340,7 @@
Handle<Code> StubCache::ComputeKeyedLoadArrayLength(Handle<String> name,
Handle<JSArray> receiver) {
Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -351,7 +356,7 @@
Handle<Code> StubCache::ComputeKeyedLoadStringLength(Handle<String> name,
Handle<String> receiver) {
Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS);
Handle<Map> map(receiver->map());
Handle<Object> probe(map->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -369,7 +374,7 @@
Handle<String> name,
Handle<JSFunction> receiver) {
Code::Flags flags =
- Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, Code::CALLBACKS);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -387,7 +392,8 @@
int field_index,
Handle<Map> transition,
StrictModeFlag strict_mode) {
- PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION;
+ Code::StubType type =
+ (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION;
Code::Flags flags = Code::ComputeMonomorphicFlags(
Code::STORE_IC, type, strict_mode);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
@@ -415,7 +421,7 @@
Code::ComputeMonomorphicFlags(
stub_kind == KeyedIC::LOAD ? Code::KEYED_LOAD_IC
: Code::KEYED_STORE_IC,
- NORMAL,
+ Code::NORMAL,
extra_state);
Handle<String> name;
switch (stub_kind) {
@@ -483,7 +489,7 @@
Handle<JSGlobalPropertyCell> cell,
StrictModeFlag strict_mode) {
Code::Flags flags = Code::ComputeMonomorphicFlags(
- Code::STORE_IC, NORMAL, strict_mode);
+ Code::STORE_IC, Code::NORMAL, strict_mode);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -502,7 +508,7 @@
StrictModeFlag strict_mode) {
ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
Code::Flags flags = Code::ComputeMonomorphicFlags(
- Code::STORE_IC, CALLBACKS, strict_mode);
+ Code::STORE_IC, Code::CALLBACKS, strict_mode);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -520,7 +526,7 @@
Handle<JSFunction> setter,
StrictModeFlag strict_mode) {
Code::Flags flags = Code::ComputeMonomorphicFlags(
- Code::STORE_IC, CALLBACKS, strict_mode);
+ Code::STORE_IC, Code::CALLBACKS, strict_mode);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -537,7 +543,7 @@
Handle<JSObject> receiver,
StrictModeFlag strict_mode) {
Code::Flags flags = Code::ComputeMonomorphicFlags(
- Code::STORE_IC, INTERCEPTOR, strict_mode);
+ Code::STORE_IC, Code::INTERCEPTOR, strict_mode);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -554,7 +560,8 @@
int field_index,
Handle<Map> transition,
StrictModeFlag strict_mode) {
- PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION;
+ Code::StubType type =
+ (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION;
Code::Flags flags = Code::ComputeMonomorphicFlags(
Code::KEYED_STORE_IC, type, strict_mode);
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
@@ -597,7 +604,7 @@
}
Code::Flags flags =
- Code::ComputeMonomorphicFlags(kind, CONSTANT_FUNCTION, extra_state,
+ Code::ComputeMonomorphicFlags(kind, Code::CONSTANT_FUNCTION, extra_state,
cache_holder, argc);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -635,7 +642,7 @@
}
Code::Flags flags =
- Code::ComputeMonomorphicFlags(kind, FIELD, extra_state,
+ Code::ComputeMonomorphicFlags(kind, Code::FIELD, extra_state,
cache_holder, argc);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -672,7 +679,7 @@
}
Code::Flags flags =
- Code::ComputeMonomorphicFlags(kind, INTERCEPTOR, extra_state,
+ Code::ComputeMonomorphicFlags(kind, Code::INTERCEPTOR, extra_state,
cache_holder, argc);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -702,7 +709,7 @@
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
Code::Flags flags =
- Code::ComputeMonomorphicFlags(kind, NORMAL, extra_state,
+ Code::ComputeMonomorphicFlags(kind, Code::NORMAL, extra_state,
cache_holder, argc);
Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -735,7 +742,7 @@
CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
Code::Flags flags =
- Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc);
+ Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc);
// Use raw_unchecked... so we don't get assert failures during GC.
UnseededNumberDictionary* dictionary =
@@ -756,7 +763,7 @@
CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
Code::Flags flags =
- Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc);
+ Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -785,7 +792,7 @@
Code::Kind kind,
Code::ExtraICState extra_state) {
Code::Flags flags =
- Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, NORMAL, argc);
+ Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, Code::NORMAL, argc);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -802,7 +809,7 @@
Code::Kind kind,
Code::ExtraICState extra_state) {
Code::Flags flags =
- Code::ComputeFlags(kind, MONOMORPHIC, extra_state, NORMAL, argc);
+ Code::ComputeFlags(kind, MONOMORPHIC, extra_state, Code::NORMAL, argc);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -819,7 +826,7 @@
ASSERT(kind == Code::KEYED_CALL_IC);
Code::Flags flags =
Code::ComputeFlags(kind, MEGAMORPHIC, Code::kNoExtraICState,
- NORMAL, argc);
+ Code::NORMAL, argc);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -838,7 +845,7 @@
Code::ExtraICState extra_state) {
Code::Flags flags =
Code::ComputeFlags(kind, MEGAMORPHIC, extra_state,
- NORMAL, argc);
+ Code::NORMAL, argc);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -858,7 +865,7 @@
// and monomorphic stubs are not mixed up together in the stub cache.
Code::Flags flags =
Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state,
- NORMAL, argc, OWN_MAP);
+ Code::NORMAL, argc, OWN_MAP);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -878,7 +885,7 @@
// the actual call ic to carry out the work.
Code::Flags flags =
Code::ComputeFlags(kind, DEBUG_BREAK, Code::kNoExtraICState,
- NORMAL, argc);
+ Code::NORMAL, argc);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -897,7 +904,7 @@
// the actual call ic to carry out the work.
Code::Flags flags =
Code::ComputeFlags(kind, DEBUG_PREPARE_STEP_IN, Code::kNoExtraICState,
- NORMAL, argc);
+ Code::NORMAL, argc);
Handle<UnseededNumberDictionary> cache =
isolate_->factory()->non_monomorphic_cache();
int entry = cache->FindEntry(isolate_, flags);
@@ -1361,7 +1368,8 @@
}
-Handle<Code> LoadStubCompiler::GetCode(PropertyType type, Handle<String> name) {
+Handle<Code> LoadStubCompiler::GetCode(Code::StubType type,
+ Handle<String> name) {
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type);
Handle<Code> code = GetCodeWithFlags(flags, name);
PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
@@ -1370,7 +1378,7 @@
}
-Handle<Code> KeyedLoadStubCompiler::GetCode(PropertyType type,
+Handle<Code> KeyedLoadStubCompiler::GetCode(Code::StubType type,
Handle<String> name,
InlineCacheState state) {
Code::Flags flags = Code::ComputeFlags(
@@ -1382,7 +1390,7 @@
}
-Handle<Code> StoreStubCompiler::GetCode(PropertyType type,
+Handle<Code> StoreStubCompiler::GetCode(Code::StubType type,
Handle<String> name) {
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_);
@@ -1393,7 +1401,7 @@
}
-Handle<Code> KeyedStoreStubCompiler::GetCode(PropertyType type,
+Handle<Code> KeyedStoreStubCompiler::GetCode(Code::StubType type,
Handle<String> name,
InlineCacheState state) {
Code::ExtraICState extra_state =
@@ -1471,7 +1479,8 @@
}
-Handle<Code> CallStubCompiler::GetCode(PropertyType type, Handle<String> name) {
+Handle<Code> CallStubCompiler::GetCode(Code::StubType type,
+ Handle<String> name) {
int argc = arguments_.immediate();
Code::Flags flags = Code::ComputeMonomorphicFlags(kind_,
type,
@@ -1487,7 +1496,7 @@
if (function->shared()->name()->IsString()) {
function_name = Handle<String>(String::cast(function->shared()->name()));
}
- return GetCode(CONSTANT_FUNCTION, function_name);
+ return GetCode(Code::CONSTANT_FUNCTION, function_name);
}
diff --git a/src/stub-cache.h b/src/stub-cache.h
index de8a76b..e274c82 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -628,7 +628,7 @@
bool is_dont_delete);
private:
- Handle<Code> GetCode(PropertyType type, Handle<String> name);
+ Handle<Code> GetCode(Code::StubType type, Handle<String> name);
};
@@ -676,7 +676,7 @@
static void GenerateLoadDictionaryElement(MacroAssembler* masm);
private:
- Handle<Code> GetCode(PropertyType type,
+ Handle<Code> GetCode(Code::StubType type,
Handle<String> name,
InlineCacheState state = MONOMORPHIC);
};
@@ -709,7 +709,7 @@
Handle<String> name);
private:
- Handle<Code> GetCode(PropertyType type, Handle<String> name);
+ Handle<Code> GetCode(Code::StubType type, Handle<String> name);
StrictModeFlag strict_mode_;
};
@@ -750,7 +750,7 @@
static void GenerateStoreDictionaryElement(MacroAssembler* masm);
private:
- Handle<Code> GetCode(PropertyType type,
+ Handle<Code> GetCode(Code::StubType type,
Handle<String> name,
InlineCacheState state = MONOMORPHIC);
@@ -830,7 +830,7 @@
Handle<JSFunction> function,
Handle<String> name);
- Handle<Code> GetCode(PropertyType type, Handle<String> name);
+ Handle<Code> GetCode(Code::StubType type, Handle<String> name);
Handle<Code> GetCode(Handle<JSFunction> function);
const ParameterCount& arguments() { return arguments_; }
diff --git a/src/type-info.cc b/src/type-info.cc
index dfdfd89..6747fec 100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -97,7 +97,7 @@
Handle<Code> code = Handle<Code>::cast(map_or_code);
return code->is_keyed_load_stub() &&
code->ic_state() == MONOMORPHIC &&
- Code::ExtractTypeFromFlags(code->flags()) == NORMAL &&
+ Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL &&
code->FindFirstMap() != NULL &&
!CanRetainOtherContext(code->FindFirstMap(), *global_context_);
}
@@ -129,7 +129,7 @@
return code->is_keyed_store_stub() &&
!allow_growth &&
code->ic_state() == MONOMORPHIC &&
- Code::ExtractTypeFromFlags(code->flags()) == NORMAL &&
+ Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL &&
code->FindFirstMap() != NULL &&
!CanRetainOtherContext(code->FindFirstMap(), *global_context_);
}
@@ -214,7 +214,8 @@
void TypeFeedbackOracle::LoadReceiverTypes(Property* expr,
Handle<String> name,
SmallMapList* types) {
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, Code::NORMAL);
CollectReceiverTypes(expr->id(), name, flags, types);
}
@@ -222,7 +223,8 @@
void TypeFeedbackOracle::StoreReceiverTypes(Assignment* expr,
Handle<String> name,
SmallMapList* types) {
- Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(Code::STORE_IC, Code::NORMAL);
CollectReceiverTypes(expr->id(), name, flags, types);
}
@@ -239,7 +241,7 @@
CallIC::Contextual::encode(call_kind == CALL_AS_FUNCTION);
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC,
- NORMAL,
+ Code::NORMAL,
extra_ic_state,
OWN_MAP,
arity);
diff --git a/src/v8-counters.h b/src/v8-counters.h
index f36b0ed..dc55042 100644
--- a/src/v8-counters.h
+++ b/src/v8-counters.h
@@ -246,7 +246,30 @@
SC(smi_checks_removed, V8.SmiChecksRemoved) \
SC(map_checks_removed, V8.MapChecksRemoved) \
SC(quote_json_char_count, V8.QuoteJsonCharacterCount) \
- SC(quote_json_char_recount, V8.QuoteJsonCharacterReCount)
+ SC(quote_json_char_recount, V8.QuoteJsonCharacterReCount) \
+ SC(new_space_bytes_available, V8.MemoryNewSpaceBytesAvailable) \
+ SC(new_space_bytes_committed, V8.MemoryNewSpaceBytesCommitted) \
+ SC(new_space_bytes_used, V8.MemoryNewSpaceBytesUsed) \
+ SC(old_pointer_space_bytes_available, \
+ V8.MemoryOldPointerSpaceBytesAvailable) \
+ SC(old_pointer_space_bytes_committed, \
+ V8.MemoryOldPointerSpaceBytesCommitted) \
+ SC(old_pointer_space_bytes_used, V8.MemoryOldPointerSpaceBytesUsed) \
+ SC(old_data_space_bytes_available, V8.MemoryOldDataSpaceBytesAvailable) \
+ SC(old_data_space_bytes_committed, V8.MemoryOldDataSpaceBytesCommitted) \
+ SC(old_data_space_bytes_used, V8.MemoryOldDataSpaceBytesUsed) \
+ SC(code_space_bytes_available, V8.MemoryCodeSpaceBytesAvailable) \
+ SC(code_space_bytes_committed, V8.MemoryCodeSpaceBytesCommitted) \
+ SC(code_space_bytes_used, V8.MemoryCodeSpaceBytesUsed) \
+ SC(map_space_bytes_available, V8.MemoryMapSpaceBytesAvailable) \
+ SC(map_space_bytes_committed, V8.MemoryMapSpaceBytesCommitted) \
+ SC(map_space_bytes_used, V8.MemoryMapSpaceBytesUsed) \
+ SC(cell_space_bytes_available, V8.MemoryCellSpaceBytesAvailable) \
+ SC(cell_space_bytes_committed, V8.MemoryCellSpaceBytesCommitted) \
+ SC(cell_space_bytes_used, V8.MemoryCellSpaceBytesUsed) \
+ SC(lo_space_bytes_available, V8.MemoryLoSpaceBytesAvailable) \
+ SC(lo_space_bytes_committed, V8.MemoryLoSpaceBytesCommitted) \
+ SC(lo_space_bytes_used, V8.MemoryLoSpaceBytesUsed)
// This file contains all the v8 counters that are in use.
diff --git a/src/version.cc b/src/version.cc
index 066713a..b62a984 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
// cannot be changed without changing the SCons build script.
#define MAJOR_VERSION 3
#define MINOR_VERSION 12
-#define BUILD_NUMBER 3
+#define BUILD_NUMBER 4
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index 9f5f850..3c1b961 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -455,6 +455,7 @@
ASSERT(initialized_);
if (f == SSE2 && !FLAG_enable_sse2) return false;
if (f == SSE3 && !FLAG_enable_sse3) return false;
+ if (f == SSE4_1 && !FLAG_enable_sse4_1) return false;
if (f == CMOV && !FLAG_enable_cmov) return false;
if (f == RDTSC && !FLAG_enable_rdtsc) return false;
if (f == SAHF && !FLAG_enable_sahf) return false;
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index a55788d..050c0d6 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -504,12 +504,20 @@
void FullCodeGenerator::AccumulatorValueContext::Plug(
Handle<Object> lit) const {
- __ Move(result_register(), lit);
+ if (lit->IsSmi()) {
+ __ SafeMove(result_register(), Smi::cast(*lit));
+ } else {
+ __ Move(result_register(), lit);
+ }
}
void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
- __ Push(lit);
+ if (lit->IsSmi()) {
+ __ SafePush(Smi::cast(*lit));
+ } else {
+ __ Push(lit);
+ }
}
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 82fdb3c..4649a42 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -823,7 +823,7 @@
Code::Flags flags = Code::ComputeFlags(kind,
MONOMORPHIC,
extra_state,
- NORMAL,
+ Code::NORMAL,
argc);
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx,
rax);
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 57db277..808c4d8 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -3031,7 +3031,6 @@
XMMRegister xmm_scratch = xmm0;
Register output_reg = ToRegister(instr->result());
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
- Label done;
if (CpuFeatures::IsSupported(SSE4_1)) {
CpuFeatures::Scope scope(SSE4_1);
@@ -3046,10 +3045,13 @@
__ cmpl(output_reg, Immediate(0x80000000));
DeoptimizeIf(equal, instr->environment());
} else {
+ Label negative_sign, done;
// Deoptimize on negative inputs.
__ xorps(xmm_scratch, xmm_scratch); // Zero the register.
__ ucomisd(input_reg, xmm_scratch);
- DeoptimizeIf(below, instr->environment());
+ DeoptimizeIf(parity_even, instr->environment());
+ __ j(below, &negative_sign, Label::kNear);
+
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
// Check for negative zero.
Label positive_sign;
@@ -3064,12 +3066,23 @@
// Use truncating instruction (OK because input is positive).
__ cvttsd2si(output_reg, input_reg);
-
// Overflow is signalled with minint.
__ cmpl(output_reg, Immediate(0x80000000));
DeoptimizeIf(equal, instr->environment());
+ __ jmp(&done, Label::kNear);
+
+ // Non-zero negative reaches here.
+ __ bind(&negative_sign);
+ // Truncate, then compare and compensate.
+ __ cvttsd2si(output_reg, input_reg);
+ __ cvtlsi2sd(xmm_scratch, output_reg);
+ __ ucomisd(input_reg, xmm_scratch);
+ __ j(equal, &done, Label::kNear);
+ __ subl(output_reg, Immediate(1));
+ DeoptimizeIf(overflow, instr->environment());
+
+ __ bind(&done);
}
- __ bind(&done);
}
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 7d5d6d3..cda7549 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -892,6 +892,38 @@
}
}
+
+bool MacroAssembler::IsUnsafeInt(const int x) {
+ static const int kMaxBits = 17;
+ return !is_intn(x, kMaxBits);
+}
+
+
+void MacroAssembler::SafeMove(Register dst, Smi* src) {
+ ASSERT(!dst.is(kScratchRegister));
+ ASSERT(kSmiValueSize == 32); // JIT cookie can be converted to Smi.
+ if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
+ Move(dst, Smi::FromInt(src->value() ^ jit_cookie()));
+ Move(kScratchRegister, Smi::FromInt(jit_cookie()));
+ xor_(dst, kScratchRegister);
+ } else {
+ Move(dst, src);
+ }
+}
+
+
+void MacroAssembler::SafePush(Smi* src) {
+ ASSERT(kSmiValueSize == 32); // JIT cookie can be converted to Smi.
+ if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
+ Push(Smi::FromInt(src->value() ^ jit_cookie()));
+ Move(kScratchRegister, Smi::FromInt(jit_cookie()));
+ xor_(Operand(rsp, 0), kScratchRegister);
+ } else {
+ Push(src);
+ }
+}
+
+
// ----------------------------------------------------------------------------
// Smi tagging, untagging and tag detection.
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index 1c1cd95..68795a4 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -774,6 +774,11 @@
// Move if the registers are not identical.
void Move(Register target, Register source);
+ // Support for constant splitting.
+ bool IsUnsafeInt(const int x);
+ void SafeMove(Register dst, Smi* src);
+ void SafePush(Smi* src);
+
// Bit-field support.
void TestBit(const Operand& dst, int bit_index);
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 4040e95..a2adf06 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -1391,7 +1391,7 @@
GenerateMissBranch();
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -1915,7 +1915,7 @@
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2030,7 +2030,7 @@
GenerateMissBranch();
// Return the generated code.
- return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name);
+ return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name);
}
@@ -2279,7 +2279,7 @@
GenerateMissBranch();
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2342,7 +2342,7 @@
GenerateMissBranch();
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2373,7 +2373,9 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
@@ -2420,7 +2422,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2466,7 +2468,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2512,7 +2514,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2560,7 +2562,7 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2599,7 +2601,9 @@
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
+ return GetCode(transition.is_null()
+ ? Code::FIELD
+ : Code::MAP_TRANSITION, name);
}
@@ -2623,7 +2627,7 @@
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -2661,7 +2665,7 @@
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
@@ -2699,7 +2703,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NONEXISTENT, factory()->empty_string());
+ return GetCode(Code::NONEXISTENT, factory()->empty_string());
}
@@ -2719,7 +2723,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -2740,7 +2744,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2778,7 +2782,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2798,7 +2802,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -2822,7 +2826,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -2866,7 +2870,7 @@
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NORMAL, name);
+ return GetCode(Code::NORMAL, name);
}
@@ -2895,7 +2899,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(FIELD, name);
+ return GetCode(Code::FIELD, name);
}
@@ -2924,7 +2928,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -2954,7 +2958,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CONSTANT_FUNCTION, name);
+ return GetCode(Code::CONSTANT_FUNCTION, name);
}
@@ -2984,7 +2988,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(INTERCEPTOR, name);
+ return GetCode(Code::INTERCEPTOR, name);
}
@@ -3010,7 +3014,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3036,7 +3040,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3062,7 +3066,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(CALLBACKS, name);
+ return GetCode(Code::CALLBACKS, name);
}
@@ -3082,7 +3086,7 @@
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string());
+ return GetCode(Code::NORMAL, factory()->empty_string());
}
@@ -3110,7 +3114,7 @@
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
- return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
+ return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC);
}
diff --git a/test/cctest/test-compiler.cc b/test/cctest/test-compiler.cc
index ac08800..cbabf3e 100644
--- a/test/cctest/test-compiler.cc
+++ b/test/cctest/test-compiler.cc
@@ -406,15 +406,16 @@
Address end = pc + decode_size;
v8::internal::EmbeddedVector<char, 128> decode_buffer;
+ v8::internal::EmbeddedVector<char, 128> smi_hex_buffer;
+ Smi* smi = Smi::FromInt(12345678);
+ OS::SNPrintF(smi_hex_buffer, "0x%lx", reinterpret_cast<intptr_t>(smi));
while (pc < end) {
int num_const = d.ConstantPoolSizeAt(pc);
if (num_const >= 0) {
pc += (num_const + 1) * kPointerSize;
} else {
pc += d.InstructionDecode(decode_buffer, pc);
- CHECK(strstr(decode_buffer.start(), "mov eax,0x178c29c") == NULL);
- CHECK(strstr(decode_buffer.start(), "push 0x178c29c") == NULL);
- CHECK(strstr(decode_buffer.start(), "0x178c29c") == NULL);
+ CHECK(strstr(decode_buffer.start(), smi_hex_buffer.start()) == NULL);
}
}
}
diff --git a/test/cctest/test-dictionary.cc b/test/cctest/test-dictionary.cc
index 793e228..a46e4f4 100644
--- a/test/cctest/test-dictionary.cc
+++ b/test/cctest/test-dictionary.cc
@@ -48,24 +48,24 @@
table = PutIntoObjectHashTable(table, a, b);
CHECK_EQ(table->NumberOfElements(), 1);
CHECK_EQ(table->Lookup(*a), *b);
- CHECK_EQ(table->Lookup(*b), HEAP->undefined_value());
+ CHECK_EQ(table->Lookup(*b), HEAP->the_hole_value());
// Keys still have to be valid after objects were moved.
HEAP->CollectGarbage(NEW_SPACE);
CHECK_EQ(table->NumberOfElements(), 1);
CHECK_EQ(table->Lookup(*a), *b);
- CHECK_EQ(table->Lookup(*b), HEAP->undefined_value());
+ CHECK_EQ(table->Lookup(*b), HEAP->the_hole_value());
// Keys that are overwritten should not change number of elements.
table = PutIntoObjectHashTable(table, a, FACTORY->NewJSArray(13));
CHECK_EQ(table->NumberOfElements(), 1);
CHECK_NE(table->Lookup(*a), *b);
- // Keys mapped to undefined should be removed permanently.
- table = PutIntoObjectHashTable(table, a, FACTORY->undefined_value());
+ // Keys mapped to the hole should be removed permanently.
+ table = PutIntoObjectHashTable(table, a, FACTORY->the_hole_value());
CHECK_EQ(table->NumberOfElements(), 0);
CHECK_EQ(table->NumberOfDeletedElements(), 1);
- CHECK_EQ(table->Lookup(*a), HEAP->undefined_value());
+ CHECK_EQ(table->Lookup(*a), HEAP->the_hole_value());
// Keys should map back to their respective values and also should get
// an identity hash code generated.
@@ -85,7 +85,7 @@
Handle<JSObject> key = FACTORY->NewJSArray(7);
CHECK(key->GetIdentityHash(ALLOW_CREATION)->ToObjectChecked()->IsSmi());
CHECK_EQ(table->FindEntry(*key), ObjectHashTable::kNotFound);
- CHECK_EQ(table->Lookup(*key), HEAP->undefined_value());
+ CHECK_EQ(table->Lookup(*key), HEAP->the_hole_value());
CHECK(key->GetIdentityHash(OMIT_CREATION)->ToObjectChecked()->IsSmi());
}
@@ -93,7 +93,7 @@
// should not get an identity hash code generated.
for (int i = 0; i < 100; i++) {
Handle<JSObject> key = FACTORY->NewJSArray(7);
- CHECK_EQ(table->Lookup(*key), HEAP->undefined_value());
+ CHECK_EQ(table->Lookup(*key), HEAP->the_hole_value());
CHECK_EQ(key->GetIdentityHash(OMIT_CREATION), HEAP->undefined_value());
}
}
@@ -134,7 +134,7 @@
FLAG_gc_interval = 0;
// Calling Lookup() should not cause GC ever.
- CHECK(table->Lookup(*key)->IsUndefined());
+ CHECK(table->Lookup(*key)->IsTheHole());
// Calling Put() should request GC by returning a failure.
CHECK(table->Put(*key, *key)->IsRetryAfterGC());
diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc
index 9d2755d..e74a312 100644
--- a/test/cctest/test-heap-profiler.cc
+++ b/test/cctest/test-heap-profiler.cc
@@ -714,9 +714,9 @@
LocalContext env;
v8::HeapProfiler::StartHeapObjectsTracking();
- // We have to call GC 5 times. In other case the garbage will be
+ // We have to call GC 6 times. In other case the garbage will be
// the reason of flakiness.
- for (int i = 0; i < 5; ++i) {
+ for (int i = 0; i < 6; ++i) {
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
}
diff --git a/test/mjsunit/harmony/collections.js b/test/mjsunit/harmony/collections.js
index 95504bc..f3db7ea 100644
--- a/test/mjsunit/harmony/collections.js
+++ b/test/mjsunit/harmony/collections.js
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -119,12 +119,12 @@
// Test expected querying behavior of Maps and WeakMaps
function TestQuery(m) {
var key = new Object;
- TestMapping(m, key, 'to-be-present');
- assertTrue(m.has(key));
- assertFalse(m.has(new Object));
- TestMapping(m, key, undefined);
- assertFalse(m.has(key));
- assertFalse(m.has(new Object));
+ var values = [ 'x', 0, +Infinity, -Infinity, true, false, null, undefined ];
+ for (var i = 0; i < values.length; i++) {
+ TestMapping(m, key, values[i]);
+ assertTrue(m.has(key));
+ assertFalse(m.has(new Object));
+ }
}
TestQuery(new Map);
TestQuery(new WeakMap);
diff --git a/test/mjsunit/math-floor-negative.js b/test/mjsunit/math-floor-negative.js
new file mode 100644
index 0000000..4cabff5
--- /dev/null
+++ b/test/mjsunit/math-floor-negative.js
@@ -0,0 +1,59 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --noenable_sse4_1 --allow-natives-syntax
+
+function test1() {
+ // Trigger overflow when converting/truncating double to integer.
+ // Divide by 10 to avoid overflow when smi-tagging at the end.
+ return Math.floor(-100000000000.5) / 10;
+}
+
+function test2() {
+ // Trigger no overflow.
+ return Math.floor(-100.2);
+}
+
+function test3() {
+ // Trigger overflow when compensating by subtracting after compare.
+ // Divide by 10 to avoid overflow when smi-tagging at the end.
+ return Math.floor(-2147483648.1) / 10;
+}
+
+test1();
+test1();
+%OptimizeFunctionOnNextCall(test1);
+test2();
+test2();
+%OptimizeFunctionOnNextCall(test2);
+test3();
+test3();
+%OptimizeFunctionOnNextCall(test3);
+
+assertEquals(-10000000000.1, test1());
+assertEquals(-101, test2());
+assertEquals(-214748364.9, test3());
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index 081d914..2d54cf0 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -183,4 +183,5 @@
debug-liveedit-check-stack: SKIP
debug-liveedit-stack-padding: SKIP
debug-liveedit-restart-frame: SKIP
+debug-liveedit-double-call: SKIP
diff --git a/test/mjsunit/regress/regress-2119.js b/test/mjsunit/regress/regress-2119.js
new file mode 100644
index 0000000..54840c2
--- /dev/null
+++ b/test/mjsunit/regress/regress-2119.js
@@ -0,0 +1,36 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --nouse-ic
+
+function strict_function() {
+ "use strict"
+ undeclared = 1;
+}
+
+assertThrows(strict_function);
+