Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(289)

Side by Side Diff: src/objects.cc

Issue 6529055: [Isolates] Merge crankshaft (r5922 from bleeding_edge). (Closed)
Patch Set: Win32 port Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 12 matching lines...) Expand all
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "api.h" 30 #include "api.h"
31 #include "arguments.h" 31 #include "arguments.h"
32 #include "bootstrapper.h" 32 #include "bootstrapper.h"
33 #include "codegen.h"
33 #include "debug.h" 34 #include "debug.h"
35 #include "deoptimizer.h"
34 #include "execution.h" 36 #include "execution.h"
37 #include "full-codegen.h"
38 #include "hydrogen.h"
35 #include "objects-inl.h" 39 #include "objects-inl.h"
36 #include "objects-visiting.h" 40 #include "objects-visiting.h"
37 #include "macro-assembler.h" 41 #include "macro-assembler.h"
42 #include "safepoint-table.h"
38 #include "scanner-base.h" 43 #include "scanner-base.h"
39 #include "scopeinfo.h" 44 #include "scopeinfo.h"
40 #include "string-stream.h" 45 #include "string-stream.h"
41 #include "utils.h" 46 #include "utils.h"
47 #include "vm-state-inl.h"
42 48
43 #ifdef ENABLE_DISASSEMBLER 49 #ifdef ENABLE_DISASSEMBLER
50 #include "disasm.h"
44 #include "disassembler.h" 51 #include "disassembler.h"
45 #endif 52 #endif
46 53
47 namespace v8 { 54 namespace v8 {
48 namespace internal { 55 namespace internal {
49 56
50 // Getters and setters are stored in a fixed array property. These are 57 // Getters and setters are stored in a fixed array property. These are
51 // constants for their indices. 58 // constants for their indices.
52 const int kGetterIndex = 0; 59 const int kGetterIndex = 0;
53 const int kSetterIndex = 1; 60 const int kSetterIndex = 1;
(...skipping 1705 matching lines...) Expand 10 before | Expand all | Expand 10 after
1759 DescriptorArray* descriptors = map()->instance_descriptors(); 1766 DescriptorArray* descriptors = map()->instance_descriptors();
1760 int number = descriptors->SearchWithCache(name); 1767 int number = descriptors->SearchWithCache(name);
1761 if (number != DescriptorArray::kNotFound) { 1768 if (number != DescriptorArray::kNotFound) {
1762 result->DescriptorResult(this, descriptors->GetDetails(number), number); 1769 result->DescriptorResult(this, descriptors->GetDetails(number), number);
1763 } else { 1770 } else {
1764 result->NotFound(); 1771 result->NotFound();
1765 } 1772 }
1766 } 1773 }
1767 1774
1768 1775
1776 void Map::LookupInDescriptors(JSObject* holder,
1777 String* name,
1778 LookupResult* result) {
1779 DescriptorArray* descriptors = instance_descriptors();
1780 DescriptorLookupCache* cache = heap()->isolate()->descriptor_lookup_cache();
1781 int number = cache->Lookup(descriptors, name);
1782 if (number == DescriptorLookupCache::kAbsent) {
1783 number = descriptors->Search(name);
1784 cache->Update(descriptors, name, number);
1785 }
1786 if (number != DescriptorArray::kNotFound) {
1787 result->DescriptorResult(holder, descriptors->GetDetails(number), number);
1788 } else {
1789 result->NotFound();
1790 }
1791 }
1792
1793
1769 void JSObject::LocalLookupRealNamedProperty(String* name, 1794 void JSObject::LocalLookupRealNamedProperty(String* name,
1770 LookupResult* result) { 1795 LookupResult* result) {
1771 if (IsJSGlobalProxy()) { 1796 if (IsJSGlobalProxy()) {
1772 Object* proto = GetPrototype(); 1797 Object* proto = GetPrototype();
1773 if (proto->IsNull()) return result->NotFound(); 1798 if (proto->IsNull()) return result->NotFound();
1774 ASSERT(proto->IsJSGlobalObject()); 1799 ASSERT(proto->IsJSGlobalObject());
1775 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result); 1800 return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result);
1776 } 1801 }
1777 1802
1778 if (HasFastProperties()) { 1803 if (HasFastProperties()) {
(...skipping 1331 matching lines...) Expand 10 before | Expand all | Expand 10 after
3110 } 3135 }
3111 3136
3112 // For the global object allocate a new map to invalidate the global inline 3137 // For the global object allocate a new map to invalidate the global inline
3113 // caches which have a global property cell reference directly in the code. 3138 // caches which have a global property cell reference directly in the code.
3114 if (IsGlobalObject()) { 3139 if (IsGlobalObject()) {
3115 Object* new_map; 3140 Object* new_map;
3116 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); 3141 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
3117 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 3142 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
3118 } 3143 }
3119 set_map(Map::cast(new_map)); 3144 set_map(Map::cast(new_map));
3145 // When running crankshaft, changing the map is not enough. We
3146 // need to deoptimize all functions that rely on this global
3147 // object.
3148 Deoptimizer::DeoptimizeGlobalObject(this);
3120 } 3149 }
3121 3150
3122 // Update the dictionary with the new CALLBACKS property. 3151 // Update the dictionary with the new CALLBACKS property.
3123 Object* result; 3152 Object* result;
3124 { MaybeObject* maybe_result = SetNormalizedProperty(name, structure, details); 3153 { MaybeObject* maybe_result = SetNormalizedProperty(name, structure, details);
3125 if (!maybe_result->ToObject(&result)) return maybe_result; 3154 if (!maybe_result->ToObject(&result)) return maybe_result;
3126 } 3155 }
3127 3156
3128 if (convert_back_to_fast) { 3157 if (convert_back_to_fast) {
3129 { MaybeObject* maybe_ok = TransformToFastProperties(0); 3158 { MaybeObject* maybe_ok = TransformToFastProperties(0);
(...skipping 1066 matching lines...) Expand 10 before | Expand all | Expand 10 after
4196 if ((entry->Hash() == hash) && 4225 if ((entry->Hash() == hash) &&
4197 name->Equals(entry) && 4226 name->Equals(entry) &&
4198 !is_null_descriptor(number)) { 4227 !is_null_descriptor(number)) {
4199 return number; 4228 return number;
4200 } 4229 }
4201 } 4230 }
4202 return kNotFound; 4231 return kNotFound;
4203 } 4232 }
4204 4233
4205 4234
4235 MaybeObject* DeoptimizationInputData::Allocate(int deopt_entry_count,
4236 PretenureFlag pretenure) {
4237 ASSERT(deopt_entry_count > 0);
4238 return HEAP->AllocateFixedArray(LengthFor(deopt_entry_count),
4239 pretenure);
4240 }
4241
4242
4243 MaybeObject* DeoptimizationOutputData::Allocate(int number_of_deopt_points,
4244 PretenureFlag pretenure) {
4245 if (number_of_deopt_points == 0) return HEAP->empty_fixed_array();
4246 return HEAP->AllocateFixedArray(LengthOfFixedArray(number_of_deopt_points),
4247 pretenure);
4248 }
4249
4250
4206 #ifdef DEBUG 4251 #ifdef DEBUG
4207 bool DescriptorArray::IsEqualTo(DescriptorArray* other) { 4252 bool DescriptorArray::IsEqualTo(DescriptorArray* other) {
4208 if (IsEmpty()) return other->IsEmpty(); 4253 if (IsEmpty()) return other->IsEmpty();
4209 if (other->IsEmpty()) return false; 4254 if (other->IsEmpty()) return false;
4210 if (length() != other->length()) return false; 4255 if (length() != other->length()) return false;
4211 for (int i = 0; i < length(); ++i) { 4256 for (int i = 0; i < length(); ++i) {
4212 if (get(i) != other->get(i) && i != kContentArrayIndex) return false; 4257 if (get(i) != other->get(i) && i != kContentArrayIndex) return false;
4213 } 4258 }
4214 return GetContentArray()->IsEqualTo(other->GetContentArray()); 4259 return GetContentArray()->IsEqualTo(other->GetContentArray());
4215 } 4260 }
4216 #endif 4261 #endif
4217 4262
4218 4263
4219 bool String::LooksValid() { 4264 bool String::LooksValid() {
4220 if (!GetHeap()->Contains(this)) return false; 4265 if (!Isolate::Current()->heap()->Contains(this)) return false;
4221 return true; 4266 return true;
4222 } 4267 }
4223 4268
4224 4269
4225 int String::Utf8Length() { 4270 int String::Utf8Length() {
4226 if (IsAsciiRepresentation()) return length(); 4271 if (IsAsciiRepresentation()) return length();
4227 // Attempt to flatten before accessing the string. It probably 4272 // Attempt to flatten before accessing the string. It probably
4228 // doesn't make Utf8Length faster, but it is very likely that 4273 // doesn't make Utf8Length faster, but it is very likely that
4229 // the string will be accessed later (for example by WriteUtf8) 4274 // the string will be accessed later (for example by WriteUtf8)
4230 // so it's still a good idea. 4275 // so it's still a good idea.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
4291 return Vector<const uc16>(start + offset, length); 4336 return Vector<const uc16>(start + offset, length);
4292 } 4337 }
4293 4338
4294 4339
4295 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, 4340 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls,
4296 RobustnessFlag robust_flag, 4341 RobustnessFlag robust_flag,
4297 int offset, 4342 int offset,
4298 int length, 4343 int length,
4299 int* length_return) { 4344 int* length_return) {
4300 ASSERT(NativeAllocationChecker::allocation_allowed()); 4345 ASSERT(NativeAllocationChecker::allocation_allowed());
4301 Heap* heap = GetHeap();
4302 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { 4346 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
4303 return SmartPointer<char>(NULL); 4347 return SmartPointer<char>(NULL);
4304 } 4348 }
4349 Heap* heap = GetHeap();
4305 4350
4306 // Negative length means the to the end of the string. 4351 // Negative length means the to the end of the string.
4307 if (length < 0) length = kMaxInt - offset; 4352 if (length < 0) length = kMaxInt - offset;
4308 4353
4309 // Compute the size of the UTF-8 string. Start at the specified offset. 4354 // Compute the size of the UTF-8 string. Start at the specified offset.
4310 Access<StringInputBuffer> buffer( 4355 Access<StringInputBuffer> buffer(
4311 heap->isolate()->objects_string_input_buffer()); 4356 heap->isolate()->objects_string_input_buffer());
4312 buffer->Reset(offset, this); 4357 buffer->Reset(offset, this);
4313 int character_position = offset; 4358 int character_position = offset;
4314 int utf8_bytes = 0; 4359 int utf8_bytes = 0;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
4370 case kConsStringTag: 4415 case kConsStringTag:
4371 UNREACHABLE(); 4416 UNREACHABLE();
4372 return NULL; 4417 return NULL;
4373 } 4418 }
4374 UNREACHABLE(); 4419 UNREACHABLE();
4375 return NULL; 4420 return NULL;
4376 } 4421 }
4377 4422
4378 4423
4379 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { 4424 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) {
4380 Heap* heap = GetHeap();
4381 ASSERT(NativeAllocationChecker::allocation_allowed()); 4425 ASSERT(NativeAllocationChecker::allocation_allowed());
4382
4383 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { 4426 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
4384 return SmartPointer<uc16>(); 4427 return SmartPointer<uc16>();
4385 } 4428 }
4429 Heap* heap = GetHeap();
4386 4430
4387 Access<StringInputBuffer> buffer( 4431 Access<StringInputBuffer> buffer(
4388 heap->isolate()->objects_string_input_buffer()); 4432 heap->isolate()->objects_string_input_buffer());
4389 buffer->Reset(this); 4433 buffer->Reset(this);
4390 4434
4391 uc16* result = NewArray<uc16>(length() + 1); 4435 uc16* result = NewArray<uc16>(length() + 1);
4392 4436
4393 int i = 0; 4437 int i = 0;
4394 while (buffer->has_more()) { 4438 while (buffer->has_more()) {
4395 uint16_t character = buffer->GetNext(); 4439 uint16_t character = buffer->GetNext();
(...skipping 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after
5416 5460
5417 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) { 5461 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) {
5418 // Iterate over all fields in the body but take care in dealing with 5462 // Iterate over all fields in the body but take care in dealing with
5419 // the code entry. 5463 // the code entry.
5420 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset); 5464 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset);
5421 v->VisitCodeEntry(this->address() + kCodeEntryOffset); 5465 v->VisitCodeEntry(this->address() + kCodeEntryOffset);
5422 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); 5466 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size);
5423 } 5467 }
5424 5468
5425 5469
5470 void JSFunction::MarkForLazyRecompilation() {
5471 ASSERT(is_compiled() && !IsOptimized());
5472 ASSERT(shared()->allows_lazy_compilation());
5473 Builtins* builtins = GetIsolate()->builtins();
5474 ReplaceCode(builtins->builtin(Builtins::LazyRecompile));
5475 }
5476
5477
5478 uint32_t JSFunction::SourceHash() {
5479 uint32_t hash = 0;
5480 Object* script = shared()->script();
5481 if (!script->IsUndefined()) {
5482 Object* source = Script::cast(script)->source();
5483 if (source->IsUndefined()) hash = String::cast(source)->Hash();
5484 }
5485 hash ^= ComputeIntegerHash(shared()->start_position_and_type());
5486 hash += ComputeIntegerHash(shared()->end_position());
5487 return hash;
5488 }
5489
5490
5491 bool JSFunction::IsInlineable() {
5492 if (IsBuiltin()) return false;
5493 // Check that the function has a script associated with it.
5494 if (!shared()->script()->IsScript()) return false;
5495 Code* code = shared()->code();
5496 if (code->kind() == Code::OPTIMIZED_FUNCTION) return true;
5497 // If we never ran this (unlikely) then lets try to optimize it.
5498 if (code->kind() != Code::FUNCTION) return true;
5499 return code->optimizable();
5500 }
5501
5502
5426 Object* JSFunction::SetInstancePrototype(Object* value) { 5503 Object* JSFunction::SetInstancePrototype(Object* value) {
5427 ASSERT(value->IsJSObject()); 5504 ASSERT(value->IsJSObject());
5428 Heap* heap = GetHeap(); 5505 Heap* heap = GetHeap();
5429 if (has_initial_map()) { 5506 if (has_initial_map()) {
5430 initial_map()->set_prototype(value); 5507 initial_map()->set_prototype(value);
5431 } else { 5508 } else {
5432 // Put the value in the initial map field until an initial map is 5509 // Put the value in the initial map field until an initial map is
5433 // needed. At that point, a new initial map is created and the 5510 // needed. At that point, a new initial map is created and the
5434 // prototype is put into the initial map where it belongs. 5511 // prototype is put into the initial map where it belongs.
5435 set_prototype_or_initial_map(value); 5512 set_prototype_or_initial_map(value);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
5478 return this; 5555 return this;
5479 } 5556 }
5480 5557
5481 5558
5482 Object* JSFunction::SetInstanceClassName(String* name) { 5559 Object* JSFunction::SetInstanceClassName(String* name) {
5483 shared()->set_instance_class_name(name); 5560 shared()->set_instance_class_name(name);
5484 return this; 5561 return this;
5485 } 5562 }
5486 5563
5487 5564
5565 void JSFunction::PrintName() {
5566 SmartPointer<char> name = shared()->DebugName()->ToCString();
5567 PrintF("%s", *name);
5568 }
5569
5570
5488 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) { 5571 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) {
5489 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex)); 5572 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex));
5490 } 5573 }
5491 5574
5492 5575
5493 MaybeObject* Oddball::Initialize(const char* to_string, 5576 MaybeObject* Oddball::Initialize(const char* to_string,
5494 Object* to_number, 5577 Object* to_number,
5495 byte kind) { 5578 byte kind) {
5496 Object* symbol; 5579 Object* symbol;
5497 { MaybeObject* maybe_symbol = 5580 { MaybeObject* maybe_symbol =
(...skipping 14 matching lines...) Expand all
5512 } 5595 }
5513 5596
5514 5597
5515 bool SharedFunctionInfo::HasSourceCode() { 5598 bool SharedFunctionInfo::HasSourceCode() {
5516 return !script()->IsUndefined() && 5599 return !script()->IsUndefined() &&
5517 !reinterpret_cast<Script*>(script())->source()->IsUndefined(); 5600 !reinterpret_cast<Script*>(script())->source()->IsUndefined();
5518 } 5601 }
5519 5602
5520 5603
5521 Object* SharedFunctionInfo::GetSourceCode() { 5604 Object* SharedFunctionInfo::GetSourceCode() {
5522 Heap* heap = GetHeap(); 5605 Isolate* isolate = GetIsolate();
5523 HandleScope scope; 5606 if (!HasSourceCode()) return isolate->heap()->undefined_value();
5524 if (script()->IsUndefined()) return heap->undefined_value(); 5607 HandleScope scope(isolate);
5525 Object* source = Script::cast(script())->source(); 5608 Object* source = Script::cast(script())->source();
5526 if (source->IsUndefined()) return heap->undefined_value(); 5609 return *SubString(Handle<String>(String::cast(source), isolate),
5527 return *SubString(Handle<String>(String::cast(source)),
5528 start_position(), end_position()); 5610 start_position(), end_position());
5529 } 5611 }
5530 5612
5531 5613
5614 int SharedFunctionInfo::SourceSize() {
5615 return end_position() - start_position();
5616 }
5617
5618
5532 int SharedFunctionInfo::CalculateInstanceSize() { 5619 int SharedFunctionInfo::CalculateInstanceSize() {
5533 int instance_size = 5620 int instance_size =
5534 JSObject::kHeaderSize + 5621 JSObject::kHeaderSize +
5535 expected_nof_properties() * kPointerSize; 5622 expected_nof_properties() * kPointerSize;
5536 if (instance_size > JSObject::kMaxInstanceSize) { 5623 if (instance_size > JSObject::kMaxInstanceSize) {
5537 instance_size = JSObject::kMaxInstanceSize; 5624 instance_size = JSObject::kMaxInstanceSize;
5538 } 5625 }
5539 return instance_size; 5626 return instance_size;
5540 } 5627 }
5541 5628
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
5642 FixedArray::cast(this_property_assignments())->get(index * 3 + 2); 5729 FixedArray::cast(this_property_assignments())->get(index * 3 + 2);
5643 return obj; 5730 return obj;
5644 } 5731 }
5645 5732
5646 5733
5647 // Support function for printing the source code to a StringStream 5734 // Support function for printing the source code to a StringStream
5648 // without any allocation in the heap. 5735 // without any allocation in the heap.
5649 void SharedFunctionInfo::SourceCodePrint(StringStream* accumulator, 5736 void SharedFunctionInfo::SourceCodePrint(StringStream* accumulator,
5650 int max_length) { 5737 int max_length) {
5651 // For some native functions there is no source. 5738 // For some native functions there is no source.
5652 if (script()->IsUndefined() || 5739 if (!HasSourceCode()) {
5653 Script::cast(script())->source()->IsUndefined()) {
5654 accumulator->Add("<No Source>"); 5740 accumulator->Add("<No Source>");
5655 return; 5741 return;
5656 } 5742 }
5657 5743
5658 // Get the source for the script which this function came from. 5744 // Get the source for the script which this function came from.
5659 // Don't use String::cast because we don't want more assertion errors while 5745 // Don't use String::cast because we don't want more assertion errors while
5660 // we are already creating a stack dump. 5746 // we are already creating a stack dump.
5661 String* script_source = 5747 String* script_source =
5662 reinterpret_cast<String*>(Script::cast(script())->source()); 5748 reinterpret_cast<String*>(Script::cast(script())->source());
5663 5749
5664 if (!script_source->LooksValid()) { 5750 if (!script_source->LooksValid()) {
5665 accumulator->Add("<Invalid Source>"); 5751 accumulator->Add("<Invalid Source>");
5666 return; 5752 return;
5667 } 5753 }
5668 5754
5669 if (!is_toplevel()) { 5755 if (!is_toplevel()) {
5670 accumulator->Add("function "); 5756 accumulator->Add("function ");
5671 Object* name = this->name(); 5757 Object* name = this->name();
5672 if (name->IsString() && String::cast(name)->length() > 0) { 5758 if (name->IsString() && String::cast(name)->length() > 0) {
5673 accumulator->PrintName(name); 5759 accumulator->PrintName(name);
5674 } 5760 }
5675 } 5761 }
5676 5762
5677 int len = end_position() - start_position(); 5763 int len = end_position() - start_position();
5678 if (len > max_length) { 5764 if (len <= max_length || max_length < 0) {
5765 accumulator->Put(script_source, start_position(), end_position());
5766 } else {
5679 accumulator->Put(script_source, 5767 accumulator->Put(script_source,
5680 start_position(), 5768 start_position(),
5681 start_position() + max_length); 5769 start_position() + max_length);
5682 accumulator->Add("...\n"); 5770 accumulator->Add("...\n");
5683 } else {
5684 accumulator->Put(script_source, start_position(), end_position());
5685 } 5771 }
5686 } 5772 }
5687 5773
5688 5774
5775 static bool IsCodeEquivalent(Code* code, Code* recompiled) {
5776 if (code->instruction_size() != recompiled->instruction_size()) return false;
5777 ByteArray* code_relocation = code->relocation_info();
5778 ByteArray* recompiled_relocation = recompiled->relocation_info();
5779 int length = code_relocation->length();
5780 if (length != recompiled_relocation->length()) return false;
5781 int compare = memcmp(code_relocation->GetDataStartAddress(),
5782 recompiled_relocation->GetDataStartAddress(),
5783 length);
5784 return compare == 0;
5785 }
5786
5787
5788 void SharedFunctionInfo::EnableDeoptimizationSupport(Code* recompiled) {
5789 ASSERT(!has_deoptimization_support());
5790 AssertNoAllocation no_allocation;
5791 Code* code = this->code();
5792 if (IsCodeEquivalent(code, recompiled)) {
5793 // Copy the deoptimization data from the recompiled code.
5794 code->set_deoptimization_data(recompiled->deoptimization_data());
5795 code->set_has_deoptimization_support(true);
5796 } else {
5797 // TODO(3025757): In case the recompiled isn't equivalent to the
5798 // old code, we have to replace it. We should try to avoid this
5799 // altogether because it flushes valuable type feedback by
5800 // effectively resetting all IC state.
5801 set_code(recompiled);
5802 }
5803 ASSERT(has_deoptimization_support());
5804 }
5805
5806
5807 bool SharedFunctionInfo::VerifyBailoutId(int id) {
5808 // TODO(srdjan): debugging ARM crashes in hydrogen. OK to disable while
5809 // we are always bailing out on ARM.
5810
5811 ASSERT(id != AstNode::kNoNumber);
5812 Code* unoptimized = code();
5813 DeoptimizationOutputData* data =
5814 DeoptimizationOutputData::cast(unoptimized->deoptimization_data());
5815 unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this);
5816 USE(ignore);
5817 return true; // Return true if there was no ASSERT.
5818 }
5819
5820
5689 void SharedFunctionInfo::StartInobjectSlackTracking(Map* map) { 5821 void SharedFunctionInfo::StartInobjectSlackTracking(Map* map) {
5690 ASSERT(!IsInobjectSlackTrackingInProgress()); 5822 ASSERT(!IsInobjectSlackTrackingInProgress());
5691 5823
5692 // Only initiate the tracking the first time. 5824 // Only initiate the tracking the first time.
5693 if (live_objects_may_exist()) return; 5825 if (live_objects_may_exist()) return;
5694 set_live_objects_may_exist(true); 5826 set_live_objects_may_exist(true);
5695 5827
5696 // No tracking during the snapshot construction phase. 5828 // No tracking during the snapshot construction phase.
5697 if (Serializer::enabled()) return; 5829 if (Serializer::enabled()) return;
5698 5830
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
5804 void ObjectVisitor::VisitCodeEntry(Address entry_address) { 5936 void ObjectVisitor::VisitCodeEntry(Address entry_address) {
5805 Object* code = Code::GetObjectFromEntryAddress(entry_address); 5937 Object* code = Code::GetObjectFromEntryAddress(entry_address);
5806 Object* old_code = code; 5938 Object* old_code = code;
5807 VisitPointer(&code); 5939 VisitPointer(&code);
5808 if (code != old_code) { 5940 if (code != old_code) {
5809 Memory::Address_at(entry_address) = reinterpret_cast<Code*>(code)->entry(); 5941 Memory::Address_at(entry_address) = reinterpret_cast<Code*>(code)->entry();
5810 } 5942 }
5811 } 5943 }
5812 5944
5813 5945
5946 void ObjectVisitor::VisitGlobalPropertyCell(RelocInfo* rinfo) {
5947 ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
5948 Object* cell = rinfo->target_cell();
5949 Object* old_cell = cell;
5950 VisitPointer(&cell);
5951 if (cell != old_cell) {
5952 rinfo->set_target_cell(reinterpret_cast<JSGlobalPropertyCell*>(cell));
5953 }
5954 }
5955
5956
5814 void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) { 5957 void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) {
5815 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && 5958 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
5816 rinfo->IsPatchedReturnSequence()) || 5959 rinfo->IsPatchedReturnSequence()) ||
5817 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && 5960 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
5818 rinfo->IsPatchedDebugBreakSlotSequence())); 5961 rinfo->IsPatchedDebugBreakSlotSequence()));
5819 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); 5962 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
5820 Object* old_target = target; 5963 Object* old_target = target;
5821 VisitPointer(&target); 5964 VisitPointer(&target);
5822 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. 5965 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target.
5823 } 5966 }
5824 5967
5825 5968
5969 void Code::InvalidateRelocation() {
5970 set_relocation_info(GetHeap()->empty_byte_array());
5971 }
5972
5973
5826 void Code::Relocate(intptr_t delta) { 5974 void Code::Relocate(intptr_t delta) {
5827 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { 5975 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) {
5828 it.rinfo()->apply(delta); 5976 it.rinfo()->apply(delta);
5829 } 5977 }
5830 CPU::FlushICache(instruction_start(), instruction_size()); 5978 CPU::FlushICache(instruction_start(), instruction_size());
5831 } 5979 }
5832 5980
5833 5981
5834 void Code::CopyFrom(const CodeDesc& desc) { 5982 void Code::CopyFrom(const CodeDesc& desc) {
5835 // copy code 5983 // copy code
5836 memmove(instruction_start(), desc.buffer, desc.instr_size); 5984 memmove(instruction_start(), desc.buffer, desc.instr_size);
5837 5985
5838 // copy reloc info 5986 // copy reloc info
5839 memmove(relocation_start(), 5987 memmove(relocation_start(),
5840 desc.buffer + desc.buffer_size - desc.reloc_size, 5988 desc.buffer + desc.buffer_size - desc.reloc_size,
5841 desc.reloc_size); 5989 desc.reloc_size);
5842 5990
5843 // unbox handles and relocate 5991 // unbox handles and relocate
5844 intptr_t delta = instruction_start() - desc.buffer; 5992 intptr_t delta = instruction_start() - desc.buffer;
5845 int mode_mask = RelocInfo::kCodeTargetMask | 5993 int mode_mask = RelocInfo::kCodeTargetMask |
5846 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | 5994 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
5995 RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) |
5847 RelocInfo::kApplyMask; 5996 RelocInfo::kApplyMask;
5848 Assembler* origin = desc.origin; // Needed to find target_object on X64. 5997 Assembler* origin = desc.origin; // Needed to find target_object on X64.
5849 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) { 5998 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
5850 RelocInfo::Mode mode = it.rinfo()->rmode(); 5999 RelocInfo::Mode mode = it.rinfo()->rmode();
5851 if (mode == RelocInfo::EMBEDDED_OBJECT) { 6000 if (mode == RelocInfo::EMBEDDED_OBJECT) {
5852 Handle<Object> p = it.rinfo()->target_object_handle(origin); 6001 Handle<Object> p = it.rinfo()->target_object_handle(origin);
5853 it.rinfo()->set_target_object(*p); 6002 it.rinfo()->set_target_object(*p);
6003 } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
6004 Handle<JSGlobalPropertyCell> cell = it.rinfo()->target_cell_handle();
6005 it.rinfo()->set_target_cell(*cell);
5854 } else if (RelocInfo::IsCodeTarget(mode)) { 6006 } else if (RelocInfo::IsCodeTarget(mode)) {
5855 // rewrite code handles in inline cache targets to direct 6007 // rewrite code handles in inline cache targets to direct
5856 // pointers to the first instruction in the code object 6008 // pointers to the first instruction in the code object
5857 Handle<Object> p = it.rinfo()->target_object_handle(origin); 6009 Handle<Object> p = it.rinfo()->target_object_handle(origin);
5858 Code* code = Code::cast(*p); 6010 Code* code = Code::cast(*p);
5859 it.rinfo()->set_target_address(code->instruction_start()); 6011 it.rinfo()->set_target_address(code->instruction_start());
5860 } else { 6012 } else {
5861 it.rinfo()->apply(delta); 6013 it.rinfo()->apply(delta);
5862 } 6014 }
5863 } 6015 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5914 if (statement_position < p && p <= position) { 6066 if (statement_position < p && p <= position) {
5915 statement_position = p; 6067 statement_position = p;
5916 } 6068 }
5917 } 6069 }
5918 it.next(); 6070 it.next();
5919 } 6071 }
5920 return statement_position; 6072 return statement_position;
5921 } 6073 }
5922 6074
5923 6075
6076 uint8_t* Code::GetSafepointEntry(Address pc) {
6077 SafepointTable table(this);
6078 unsigned pc_offset = pc - instruction_start();
6079 for (unsigned i = 0; i < table.length(); i++) {
6080 // TODO(kasperl): Replace the linear search with binary search.
6081 if (table.GetPcOffset(i) == pc_offset) return table.GetEntry(i);
6082 }
6083 return NULL;
6084 }
6085
6086
6087 void Code::SetNoStackCheckTable() {
6088 // Indicate the absence of a stack-check table by a table start after the
6089 // end of the instructions. Table start must be aligned, so round up.
6090 set_stack_check_table_start(RoundUp(instruction_size(), kIntSize));
6091 }
6092
6093
6094 Map* Code::FindFirstMap() {
6095 ASSERT(is_inline_cache_stub());
6096 AssertNoAllocation no_allocation;
6097 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
6098 for (RelocIterator it(this, mask); !it.done(); it.next()) {
6099 RelocInfo* info = it.rinfo();
6100 Object* object = info->target_object();
6101 if (object->IsMap()) return Map::cast(object);
6102 }
6103 return NULL;
6104 }
6105
6106
5924 #ifdef ENABLE_DISASSEMBLER 6107 #ifdef ENABLE_DISASSEMBLER
6108
6109 #ifdef DEBUG
6110
6111 void DeoptimizationInputData::DeoptimizationInputDataPrint() {
6112 disasm::NameConverter converter;
6113 int deopt_count = DeoptCount();
6114 PrintF("Deoptimization Input Data (deopt points = %d)\n", deopt_count);
6115 if (0 == deopt_count) return;
6116
6117 PrintF("%6s %6s %6s %12s\n", "index", "ast id", "argc", "commands");
6118 for (int i = 0; i < deopt_count; i++) {
6119 int command_count = 0;
6120 PrintF("%6d %6d %6d",
6121 i, AstId(i)->value(), ArgumentsStackHeight(i)->value());
6122 int translation_index = TranslationIndex(i)->value();
6123 TranslationIterator iterator(TranslationByteArray(), translation_index);
6124 Translation::Opcode opcode =
6125 static_cast<Translation::Opcode>(iterator.Next());
6126 ASSERT(Translation::BEGIN == opcode);
6127 int frame_count = iterator.Next();
6128 if (FLAG_print_code_verbose) {
6129 PrintF(" %s {count=%d}\n", Translation::StringFor(opcode), frame_count);
6130 }
6131
6132 for (int i = 0; i < frame_count; ++i) {
6133 opcode = static_cast<Translation::Opcode>(iterator.Next());
6134 ASSERT(Translation::FRAME == opcode);
6135 int ast_id = iterator.Next();
6136 int function_id = iterator.Next();
6137 JSFunction* function =
6138 JSFunction::cast(LiteralArray()->get(function_id));
6139 unsigned height = iterator.Next();
6140 if (FLAG_print_code_verbose) {
6141 PrintF("%24s %s {ast_id=%d, function=",
6142 "", Translation::StringFor(opcode), ast_id);
6143 function->PrintName();
6144 PrintF(", height=%u}\n", height);
6145 }
6146
6147 // Size of translation is height plus all incoming arguments including
6148 // receiver.
6149 int size = height + function->shared()->formal_parameter_count() + 1;
6150 command_count += size;
6151 for (int j = 0; j < size; ++j) {
6152 opcode = static_cast<Translation::Opcode>(iterator.Next());
6153 if (FLAG_print_code_verbose) {
6154 PrintF("%24s %s ", "", Translation::StringFor(opcode));
6155 }
6156
6157 if (opcode == Translation::DUPLICATE) {
6158 opcode = static_cast<Translation::Opcode>(iterator.Next());
6159 if (FLAG_print_code_verbose) {
6160 PrintF("%s ", Translation::StringFor(opcode));
6161 }
6162 --j; // Two commands share the same frame index.
6163 }
6164
6165 switch (opcode) {
6166 case Translation::BEGIN:
6167 case Translation::FRAME:
6168 case Translation::DUPLICATE:
6169 UNREACHABLE();
6170 break;
6171
6172 case Translation::REGISTER: {
6173 int reg_code = iterator.Next();
6174 if (FLAG_print_code_verbose) {
6175 PrintF("{input=%s}", converter.NameOfCPURegister(reg_code));
6176 }
6177 break;
6178 }
6179
6180 case Translation::INT32_REGISTER: {
6181 int reg_code = iterator.Next();
6182 if (FLAG_print_code_verbose) {
6183 PrintF("{input=%s}", converter.NameOfCPURegister(reg_code));
6184 }
6185 break;
6186 }
6187
6188 case Translation::DOUBLE_REGISTER: {
6189 int reg_code = iterator.Next();
6190 if (FLAG_print_code_verbose) {
6191 PrintF("{input=%s}",
6192 DoubleRegister::AllocationIndexToString(reg_code));
6193 }
6194 break;
6195 }
6196
6197 case Translation::STACK_SLOT: {
6198 int input_slot_index = iterator.Next();
6199 if (FLAG_print_code_verbose) {
6200 PrintF("{input=%d}", input_slot_index);
6201 }
6202 break;
6203 }
6204
6205 case Translation::INT32_STACK_SLOT: {
6206 int input_slot_index = iterator.Next();
6207 if (FLAG_print_code_verbose) {
6208 PrintF("{input=%d}", input_slot_index);
6209 }
6210 break;
6211 }
6212
6213 case Translation::DOUBLE_STACK_SLOT: {
6214 int input_slot_index = iterator.Next();
6215 if (FLAG_print_code_verbose) {
6216 PrintF("{input=%d}", input_slot_index);
6217 }
6218 break;
6219 }
6220
6221 case Translation::LITERAL: {
6222 unsigned literal_index = iterator.Next();
6223 if (FLAG_print_code_verbose) {
6224 PrintF("{literal_id=%u}", literal_index);
6225 }
6226 break;
6227 }
6228
6229 case Translation::ARGUMENTS_OBJECT:
6230 break;
6231 }
6232 if (FLAG_print_code_verbose) PrintF("\n");
6233 }
6234 }
6235 if (!FLAG_print_code_verbose) PrintF(" %12d\n", command_count);
6236 }
6237 }
6238
6239
6240 void DeoptimizationOutputData::DeoptimizationOutputDataPrint() {
6241 PrintF("Deoptimization Output Data (deopt points = %d)\n",
6242 this->DeoptPoints());
6243 if (this->DeoptPoints() == 0) return;
6244
6245 PrintF("%6s %8s %s\n", "ast id", "pc", "state");
6246 for (int i = 0; i < this->DeoptPoints(); i++) {
6247 int pc_and_state = this->PcAndState(i)->value();
6248 PrintF("%6d %8d %s\n",
6249 this->AstId(i)->value(),
6250 FullCodeGenerator::PcField::decode(pc_and_state),
6251 FullCodeGenerator::State2String(
6252 FullCodeGenerator::StateField::decode(pc_and_state)));
6253 }
6254 }
6255
6256 #endif
6257
6258
5925 // Identify kind of code. 6259 // Identify kind of code.
5926 const char* Code::Kind2String(Kind kind) { 6260 const char* Code::Kind2String(Kind kind) {
5927 switch (kind) { 6261 switch (kind) {
5928 case FUNCTION: return "FUNCTION"; 6262 case FUNCTION: return "FUNCTION";
6263 case OPTIMIZED_FUNCTION: return "OPTIMIZED_FUNCTION";
5929 case STUB: return "STUB"; 6264 case STUB: return "STUB";
5930 case BUILTIN: return "BUILTIN"; 6265 case BUILTIN: return "BUILTIN";
5931 case LOAD_IC: return "LOAD_IC"; 6266 case LOAD_IC: return "LOAD_IC";
5932 case KEYED_LOAD_IC: return "KEYED_LOAD_IC"; 6267 case KEYED_LOAD_IC: return "KEYED_LOAD_IC";
5933 case STORE_IC: return "STORE_IC"; 6268 case STORE_IC: return "STORE_IC";
5934 case KEYED_STORE_IC: return "KEYED_STORE_IC"; 6269 case KEYED_STORE_IC: return "KEYED_STORE_IC";
5935 case CALL_IC: return "CALL_IC"; 6270 case CALL_IC: return "CALL_IC";
5936 case KEYED_CALL_IC: return "KEYED_CALL_IC"; 6271 case KEYED_CALL_IC: return "KEYED_CALL_IC";
5937 case BINARY_OP_IC: return "BINARY_OP_IC"; 6272 case BINARY_OP_IC: return "BINARY_OP_IC";
6273 case TYPE_RECORDING_BINARY_OP_IC: return "TYPE_RECORDING_BINARY_OP_IC";
6274 case COMPARE_IC: return "COMPARE_IC";
5938 } 6275 }
5939 UNREACHABLE(); 6276 UNREACHABLE();
5940 return NULL; 6277 return NULL;
5941 } 6278 }
5942 6279
5943 6280
5944 const char* Code::ICState2String(InlineCacheState state) { 6281 const char* Code::ICState2String(InlineCacheState state) {
5945 switch (state) { 6282 switch (state) {
5946 case UNINITIALIZED: return "UNINITIALIZED"; 6283 case UNINITIALIZED: return "UNINITIALIZED";
5947 case PREMONOMORPHIC: return "PREMONOMORPHIC"; 6284 case PREMONOMORPHIC: return "PREMONOMORPHIC";
(...skipping 16 matching lines...) Expand all
5964 case CALLBACKS: return "CALLBACKS"; 6301 case CALLBACKS: return "CALLBACKS";
5965 case INTERCEPTOR: return "INTERCEPTOR"; 6302 case INTERCEPTOR: return "INTERCEPTOR";
5966 case MAP_TRANSITION: return "MAP_TRANSITION"; 6303 case MAP_TRANSITION: return "MAP_TRANSITION";
5967 case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION"; 6304 case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION";
5968 case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR"; 6305 case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR";
5969 } 6306 }
5970 UNREACHABLE(); 6307 UNREACHABLE();
5971 return NULL; 6308 return NULL;
5972 } 6309 }
5973 6310
6311
5974 void Code::Disassemble(const char* name) { 6312 void Code::Disassemble(const char* name) {
5975 PrintF("kind = %s\n", Kind2String(kind())); 6313 PrintF("kind = %s\n", Kind2String(kind()));
5976 if (is_inline_cache_stub()) { 6314 if (is_inline_cache_stub()) {
5977 PrintF("ic_state = %s\n", ICState2String(ic_state())); 6315 PrintF("ic_state = %s\n", ICState2String(ic_state()));
5978 PrintF("ic_in_loop = %d\n", ic_in_loop() == IN_LOOP); 6316 PrintF("ic_in_loop = %d\n", ic_in_loop() == IN_LOOP);
5979 if (ic_state() == MONOMORPHIC) { 6317 if (ic_state() == MONOMORPHIC) {
5980 PrintF("type = %s\n", PropertyType2String(type())); 6318 PrintF("type = %s\n", PropertyType2String(type()));
5981 } 6319 }
5982 } 6320 }
5983 if ((name != NULL) && (name[0] != '\0')) { 6321 if ((name != NULL) && (name[0] != '\0')) {
5984 PrintF("name = %s\n", name); 6322 PrintF("name = %s\n", name);
5985 } 6323 }
6324 if (kind() == OPTIMIZED_FUNCTION) {
6325 PrintF("stack_slots = %d\n", stack_slots());
6326 }
5986 6327
5987 PrintF("Instructions (size = %d)\n", instruction_size()); 6328 PrintF("Instructions (size = %d)\n", instruction_size());
5988 Disassembler::Decode(NULL, this); 6329 Disassembler::Decode(NULL, this);
5989 PrintF("\n"); 6330 PrintF("\n");
5990 6331
6332 #ifdef DEBUG
6333 if (kind() == FUNCTION) {
6334 DeoptimizationOutputData* data =
6335 DeoptimizationOutputData::cast(this->deoptimization_data());
6336 data->DeoptimizationOutputDataPrint();
6337 } else if (kind() == OPTIMIZED_FUNCTION) {
6338 DeoptimizationInputData* data =
6339 DeoptimizationInputData::cast(this->deoptimization_data());
6340 data->DeoptimizationInputDataPrint();
6341 }
6342 PrintF("\n");
6343 #endif
6344
6345 if (kind() == OPTIMIZED_FUNCTION) {
6346 SafepointTable table(this);
6347 PrintF("Safepoints (size = %u)\n", table.size());
6348 for (unsigned i = 0; i < table.length(); i++) {
6349 unsigned pc_offset = table.GetPcOffset(i);
6350 PrintF("%p %4d ", (instruction_start() + pc_offset), pc_offset);
6351 table.PrintEntry(i);
6352 PrintF(" (sp -> fp)");
6353 int deoptimization_index = table.GetDeoptimizationIndex(i);
6354 if (deoptimization_index != Safepoint::kNoDeoptimizationIndex) {
6355 PrintF(" %6d", deoptimization_index);
6356 } else {
6357 PrintF(" <none>");
6358 }
6359 PrintF("\n");
6360 }
6361 PrintF("\n");
6362 } else if (kind() == FUNCTION) {
6363 unsigned offset = stack_check_table_start();
6364 // If there is no stack check table, the "table start" will at or after
6365 // (due to alignment) the end of the instruction stream.
6366 if (static_cast<int>(offset) < instruction_size()) {
6367 unsigned* address =
6368 reinterpret_cast<unsigned*>(instruction_start() + offset);
6369 unsigned length = address[0];
6370 PrintF("Stack checks (size = %u)\n", length);
6371 PrintF("ast_id pc_offset\n");
6372 for (unsigned i = 0; i < length; ++i) {
6373 unsigned index = (2 * i) + 1;
6374 PrintF("%6u %9u\n", address[index], address[index + 1]);
6375 }
6376 PrintF("\n");
6377 }
6378 }
6379
5991 PrintF("RelocInfo (size = %d)\n", relocation_size()); 6380 PrintF("RelocInfo (size = %d)\n", relocation_size());
5992 for (RelocIterator it(this); !it.done(); it.next()) 6381 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print();
5993 it.rinfo()->Print();
5994 PrintF("\n"); 6382 PrintF("\n");
5995 } 6383 }
5996 #endif // ENABLE_DISASSEMBLER 6384 #endif // ENABLE_DISASSEMBLER
5997 6385
5998 6386
5999 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity, 6387 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity,
6000 int length) { 6388 int length) {
6001 Heap* heap = GetHeap(); 6389 Heap* heap = GetHeap();
6002 // We should never end in here with a pixel or external array. 6390 // We should never end in here with a pixel or external array.
6003 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); 6391 ASSERT(!HasPixelElements() && !HasExternalArrayElements());
(...skipping 2374 matching lines...) Expand 10 before | Expand all | Expand 10 after
8378 // Clamp undefined to zero (default). All other types have been 8766 // Clamp undefined to zero (default). All other types have been
8379 // converted to a number type further up in the call chain. 8767 // converted to a number type further up in the call chain.
8380 ASSERT(value->IsUndefined()); 8768 ASSERT(value->IsUndefined());
8381 } 8769 }
8382 set(index, cast_value); 8770 set(index, cast_value);
8383 } 8771 }
8384 return heap->AllocateHeapNumber(cast_value); 8772 return heap->AllocateHeapNumber(cast_value);
8385 } 8773 }
8386 8774
8387 8775
8388 Object* GlobalObject::GetPropertyCell(LookupResult* result) { 8776 JSGlobalPropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) {
8389 ASSERT(!HasFastProperties()); 8777 ASSERT(!HasFastProperties());
8390 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 8778 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
8391 ASSERT(value->IsJSGlobalPropertyCell()); 8779 return JSGlobalPropertyCell::cast(value);
8392 return value;
8393 } 8780 }
8394 8781
8395 8782
8396 MaybeObject* GlobalObject::EnsurePropertyCell(String* name) { 8783 MaybeObject* GlobalObject::EnsurePropertyCell(String* name) {
8397 ASSERT(!HasFastProperties()); 8784 ASSERT(!HasFastProperties());
8398 Heap* heap = GetHeap(); 8785 Heap* heap = GetHeap();
8399 int entry = property_dictionary()->FindEntry(name); 8786 int entry = property_dictionary()->FindEntry(name);
8400 if (entry == StringDictionary::kNotFound) { 8787 if (entry == StringDictionary::kNotFound) {
8401 Object* cell; 8788 Object* cell;
8402 { MaybeObject* maybe_cell = 8789 { MaybeObject* maybe_cell =
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
8641 int entry = cache->FindInsertionEntry(key.Hash()); 9028 int entry = cache->FindInsertionEntry(key.Hash());
8642 // We store the value in the key slot, and compare the search key 9029 // We store the value in the key slot, and compare the search key
8643 // to the stored value with a custon IsMatch function during lookups. 9030 // to the stored value with a custon IsMatch function during lookups.
8644 cache->set(EntryToIndex(entry), value); 9031 cache->set(EntryToIndex(entry), value);
8645 cache->set(EntryToIndex(entry) + 1, value); 9032 cache->set(EntryToIndex(entry) + 1, value);
8646 cache->ElementAdded(); 9033 cache->ElementAdded();
8647 return cache; 9034 return cache;
8648 } 9035 }
8649 9036
8650 9037
9038 void CompilationCacheTable::Remove(Object* value) {
9039 Object* null_value = GetHeap()->null_value();
9040 for (int entry = 0, size = Capacity(); entry < size; entry++) {
9041 int entry_index = EntryToIndex(entry);
9042 int value_index = entry_index + 1;
9043 if (get(value_index) == value) {
9044 fast_set(this, entry_index, null_value);
9045 fast_set(this, value_index, null_value);
9046 ElementRemoved();
9047 }
9048 }
9049 return;
9050 }
9051
9052
8651 // SymbolsKey used for HashTable where key is array of symbols. 9053 // SymbolsKey used for HashTable where key is array of symbols.
8652 class SymbolsKey : public HashTableKey { 9054 class SymbolsKey : public HashTableKey {
8653 public: 9055 public:
8654 explicit SymbolsKey(FixedArray* symbols) : symbols_(symbols) { } 9056 explicit SymbolsKey(FixedArray* symbols) : symbols_(symbols) { }
8655 9057
8656 bool IsMatch(Object* symbols) { 9058 bool IsMatch(Object* symbols) {
8657 FixedArray* o = FixedArray::cast(symbols); 9059 FixedArray* o = FixedArray::cast(symbols);
8658 int len = symbols_->length(); 9060 int len = symbols_->length();
8659 if (o->length() != len) return false; 9061 if (o->length() != len) return false;
8660 for (int i = 0; i < len; i++) { 9062 for (int i = 0; i < len; i++) {
(...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after
9442 if (break_point_objects()->IsUndefined()) return 0; 9844 if (break_point_objects()->IsUndefined()) return 0;
9443 // Single beak point. 9845 // Single beak point.
9444 if (!break_point_objects()->IsFixedArray()) return 1; 9846 if (!break_point_objects()->IsFixedArray()) return 1;
9445 // Multiple break points. 9847 // Multiple break points.
9446 return FixedArray::cast(break_point_objects())->length(); 9848 return FixedArray::cast(break_point_objects())->length();
9447 } 9849 }
9448 #endif 9850 #endif
9449 9851
9450 9852
9451 } } // namespace v8::internal 9853 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698