14a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org// Copyright 2013 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
6196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/accessors.h"
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/allocation-site-scopes.h"
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/api.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arguments.h"
1121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org#include "src/base/bits.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bootstrapper.h"
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/code-stubs.h"
144b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/codegen.h"
15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/cpu-profiler.h"
164b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/date.h"
17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h"
18196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/deoptimizer.h"
19196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/elements.h"
20196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/execution.h"
21e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org#include "src/field-index-inl.h"
224b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/field-index.h"
23196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/full-codegen.h"
243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#include "src/heap/mark-compact.h"
258640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org#include "src/heap/objects-visiting-inl.h"
26196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen.h"
27d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org#include "src/ic/ic.h"
28196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate-inl.h"
29196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/log.h"
308ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org#include "src/lookup.h"
31196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/macro-assembler.h"
324b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/objects-inl.h"
339bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org#include "src/prototype.h"
34196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/safepoint-table.h"
35196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/string-search.h"
36196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/string-stream.h"
37196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/utils.h"
3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager#ifdef ENABLE_DISASSEMBLER
40196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/disasm.h"
41196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/disassembler.h"
4231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager#endif
4331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
4471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
4571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
4643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
47e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgHandle<HeapType> Object::OptimalType(Isolate* isolate,
48e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                     Representation representation) {
495aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  if (representation.IsNone()) return HeapType::None(isolate);
508496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (FLAG_track_field_types) {
518496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    if (representation.IsHeapObject() && IsHeapObject()) {
528496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      // We can track only JavaScript objects with stable maps.
538496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      Handle<Map> map(HeapObject::cast(this)->map(), isolate);
548496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      if (map->is_stable() &&
558496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
568496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE) {
578496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        return HeapType::Class(map, isolate);
588496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      }
59e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    }
60e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  }
61e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return HeapType::Any(isolate);
62e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org}
63e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
64e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
6574dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.orgMaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
6674dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org                                         Handle<Object> object,
6774dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org                                         Handle<Context> native_context) {
6874dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
6974dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  Handle<JSFunction> constructor;
7074dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  if (object->IsNumber()) {
7174dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org    constructor = handle(native_context->number_function(), isolate);
7274dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  } else if (object->IsBoolean()) {
7374dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org    constructor = handle(native_context->boolean_function(), isolate);
7474dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  } else if (object->IsString()) {
7574dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org    constructor = handle(native_context->string_function(), isolate);
7674dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  } else if (object->IsSymbol()) {
7774dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org    constructor = handle(native_context->symbol_function(), isolate);
7874dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  } else {
7974dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org    return MaybeHandle<JSReceiver>();
80303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
8174dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
8274dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  Handle<JSValue>::cast(result)->set_value(*object);
8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
8543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
879faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.orgbool Object::BooleanValue() {
889faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  if (IsBoolean()) return IsTrue();
899faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  if (IsSmi()) return Smi::cast(this)->value() != 0;
909faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  if (IsUndefined() || IsNull()) return false;
919faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  if (IsUndetectableObject()) return false;   // Undetectable object is false.
929faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  if (IsString()) return String::cast(this)->length() != 0;
939faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  if (IsHeapNumber()) return HeapNumber::cast(this)->HeapNumberBooleanValue();
949faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  return true;
9543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
9643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgbool Object::IsCallable() const {
9908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const Object* fun = this;
1009f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  while (fun->IsJSFunctionProxy()) {
1019f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org    fun = JSFunctionProxy::cast(fun)->call_trap();
1029f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  }
1039f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  return fun->IsJSFunction() ||
1049f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org         (fun->IsHeapObject() &&
1059f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org          HeapObject::cast(fun)->map()->has_instance_call_handler());
1069f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org}
1079f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org
1089f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org
1098ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orgMaybeHandle<Object> Object::GetProperty(LookupIterator* it) {
1108ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  for (; it->IsFound(); it->Next()) {
1118ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org    switch (it->state()) {
1128ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org      case LookupIterator::NOT_FOUND:
113a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      case LookupIterator::TRANSITION:
1148ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org        UNREACHABLE();
1158ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org      case LookupIterator::JSPROXY:
116f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org        return JSProxy::GetPropertyWithHandler(it->GetHolder<JSProxy>(),
117f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org                                               it->GetReceiver(), it->name());
1188ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org      case LookupIterator::INTERCEPTOR: {
1198ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org        MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithInterceptor(
120f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org            it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
1218ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org        if (!maybe_result.is_null()) return maybe_result;
1228ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org        if (it->isolate()->has_pending_exception()) return maybe_result;
1238ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org        break;
1248ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org      }
1251845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      case LookupIterator::ACCESS_CHECK:
1268ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org        if (it->HasAccess(v8::ACCESS_GET)) break;
1278ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org        return JSObject::GetPropertyWithFailedAccessCheck(it);
1281af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      case LookupIterator::ACCESSOR:
1291af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
1301af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org                                       it->GetHolder<JSObject>(),
1311af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org                                       it->GetAccessors());
1321af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      case LookupIterator::DATA:
1331af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        return it->GetDataValue();
1348ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org    }
1358ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  }
1368ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  return it->factory()->undefined_value();
137dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org}
138dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org
139dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org
1407dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.orgHandle<Object> JSObject::GetDataProperty(Handle<JSObject> object,
1417dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org                                         Handle<Name> key) {
1429aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  LookupIterator it(object, key,
1439aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org                    LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
144e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  return GetDataProperty(&it);
145e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
146e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
147e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
148e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgHandle<Object> JSObject::GetDataProperty(LookupIterator* it) {
149e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  for (; it->IsFound(); it->Next()) {
150e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    switch (it->state()) {
1517dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      case LookupIterator::INTERCEPTOR:
152a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      case LookupIterator::NOT_FOUND:
153a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      case LookupIterator::TRANSITION:
1547dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org        UNREACHABLE();
1559aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      case LookupIterator::ACCESS_CHECK:
1569aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org        if (it->HasAccess(v8::ACCESS_GET)) continue;
1579aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      // Fall through.
1587dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      case LookupIterator::JSPROXY:
159e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        it->NotFound();
160e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        return it->isolate()->factory()->undefined_value();
1611af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      case LookupIterator::ACCESSOR:
1621af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        // TODO(verwaest): For now this doesn't call into
1631af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        // ExecutableAccessorInfo, since clients don't need it. Update once
1641af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        // relevant.
1651af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        it->NotFound();
1661af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        return it->isolate()->factory()->undefined_value();
1671af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      case LookupIterator::DATA:
1681af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        return it->GetDataValue();
1697dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    }
1707dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  }
171e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  return it->isolate()->factory()->undefined_value();
1727dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org}
1737dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
1747dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
175d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgbool Object::ToInt32(int32_t* value) {
176d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  if (IsSmi()) {
177d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    *value = Smi::cast(this)->value();
178d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    return true;
179d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
180d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  if (IsHeapNumber()) {
181d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    double num = HeapNumber::cast(this)->value();
182d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    if (FastI2D(FastD2I(num)) == num) {
183d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      *value = FastD2I(num);
184d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      return true;
185d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    }
186d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
187d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  return false;
188d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
189d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
190d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
191d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgbool Object::ToUint32(uint32_t* value) {
192d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  if (IsSmi()) {
193d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    int num = Smi::cast(this)->value();
194d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    if (num >= 0) {
195d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      *value = static_cast<uint32_t>(num);
196d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      return true;
197d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    }
198d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
199d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  if (IsHeapNumber()) {
200d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    double num = HeapNumber::cast(this)->value();
201d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    if (num >= 0 && FastUI2D(FastD2UI(num)) == num) {
202d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      *value = FastD2UI(num);
203d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      return true;
204d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    }
205d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
206d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  return false;
207d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
208d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
209d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
2109af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.orgbool FunctionTemplateInfo::IsTemplateFor(Object* object) {
2119af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  if (!object->IsHeapObject()) return false;
2129af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return IsTemplateFor(HeapObject::cast(object)->map());
2139af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org}
2149af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
2159af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
2169af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.orgbool FunctionTemplateInfo::IsTemplateFor(Map* map) {
2179af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  // There is a constraint on the object; check.
2189af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  if (!map->IsJSObjectMap()) return false;
2199af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  // Fetch the constructor function of the object.
2209af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  Object* cons_obj = map->constructor();
2219af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  if (!cons_obj->IsJSFunction()) return false;
2229af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  JSFunction* fun = JSFunction::cast(cons_obj);
2239af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  // Iterate through the chain of inheriting function templates to
2249af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  // see if the required one occurs.
2259af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  for (Object* type = fun->shared()->function_data();
2269af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org       type->IsFunctionTemplateInfo();
2279af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org       type = FunctionTemplateInfo::cast(type)->parent_template()) {
2289af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org    if (type == this) return true;
2299af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  }
2309af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  // Didn't find the required type in the inheritance chain.
2319af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return false;
2329af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org}
2339af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
2349af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
235750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgtemplate<typename To>
236750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgstatic inline To* CheckedCast(void *from) {
237750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  uintptr_t temp = reinterpret_cast<uintptr_t>(from);
238e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(temp % sizeof(To) == 0);
239750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return reinterpret_cast<To*>(temp);
240750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
241750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
242750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
243e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgstatic Handle<Object> PerformCompare(const BitmaskCompareDescriptor& descriptor,
244e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                     char* ptr,
245e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                     Isolate* isolate) {
246750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  uint32_t bitmask = descriptor.bitmask;
247750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  uint32_t compare_value = descriptor.compare_value;
248750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  uint32_t value;
249750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  switch (descriptor.size) {
250750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    case 1:
251750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      value = static_cast<uint32_t>(*CheckedCast<uint8_t>(ptr));
252750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      compare_value &= 0xff;
253750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      bitmask &= 0xff;
254750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      break;
255750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    case 2:
256750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      value = static_cast<uint32_t>(*CheckedCast<uint16_t>(ptr));
257750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      compare_value &= 0xffff;
258750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      bitmask &= 0xffff;
259750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      break;
260750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    case 4:
261750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      value = *CheckedCast<uint32_t>(ptr);
262750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      break;
263750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    default:
264750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      UNREACHABLE();
265e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      return isolate->factory()->undefined_value();
266750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
267e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return isolate->factory()->ToBoolean(
268e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      (bitmask & value) == (bitmask & compare_value));
269750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
270750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
271750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
272e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgstatic Handle<Object> PerformCompare(const PointerCompareDescriptor& descriptor,
273e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                     char* ptr,
274e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                     Isolate* isolate) {
275750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  uintptr_t compare_value =
276750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      reinterpret_cast<uintptr_t>(descriptor.compare_value);
277750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  uintptr_t value = *CheckedCast<uintptr_t>(ptr);
278e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return isolate->factory()->ToBoolean(compare_value == value);
279750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
280750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
281750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
282e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgstatic Handle<Object> GetPrimitiveValue(
283750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    const PrimitiveValueDescriptor& descriptor,
284750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    char* ptr,
285e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Isolate* isolate) {
286750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  int32_t int32_value = 0;
287750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  switch (descriptor.data_type) {
288750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    case kDescriptorInt8Type:
289750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      int32_value = *CheckedCast<int8_t>(ptr);
290750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      break;
291750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    case kDescriptorUint8Type:
292750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      int32_value = *CheckedCast<uint8_t>(ptr);
293750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      break;
294750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    case kDescriptorInt16Type:
295750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      int32_value = *CheckedCast<int16_t>(ptr);
296750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      break;
297750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    case kDescriptorUint16Type:
298750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      int32_value = *CheckedCast<uint16_t>(ptr);
299750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      break;
300750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    case kDescriptorInt32Type:
301750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      int32_value = *CheckedCast<int32_t>(ptr);
302750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      break;
303750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    case kDescriptorUint32Type: {
304750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      uint32_t value = *CheckedCast<uint32_t>(ptr);
305e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      AllowHeapAllocation allow_gc;
306e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      return isolate->factory()->NewNumberFromUint(value);
307750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    }
308750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    case kDescriptorBoolType: {
309750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      uint8_t byte = *CheckedCast<uint8_t>(ptr);
310e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      return isolate->factory()->ToBoolean(
311e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org          byte & (0x1 << descriptor.bool_offset));
312750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    }
313750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    case kDescriptorFloatType: {
314750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      float value = *CheckedCast<float>(ptr);
315e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      AllowHeapAllocation allow_gc;
316e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      return isolate->factory()->NewNumber(value);
317750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    }
318750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    case kDescriptorDoubleType: {
319750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      double value = *CheckedCast<double>(ptr);
320e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      AllowHeapAllocation allow_gc;
321e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      return isolate->factory()->NewNumber(value);
322750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    }
323750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
324e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  AllowHeapAllocation allow_gc;
325e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return isolate->factory()->NewNumberFromInt(int32_value);
326750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
327750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
328750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
329e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgstatic Handle<Object> GetDeclaredAccessorProperty(
330e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<Object> receiver,
331e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<DeclaredAccessorInfo> info,
332e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Isolate* isolate) {
333e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  DisallowHeapAllocation no_gc;
334e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  char* current = reinterpret_cast<char*>(*receiver);
335750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  DeclaredAccessorDescriptorIterator iterator(info->descriptor());
336750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  while (true) {
337750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    const DeclaredAccessorDescriptorData* data = iterator.Next();
338750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    switch (data->type) {
339750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      case kDescriptorReturnObject: {
340e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(iterator.Complete());
341750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        current = *CheckedCast<char*>(current);
342e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        return handle(*CheckedCast<Object*>(current), isolate);
343750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      }
344750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      case kDescriptorPointerDereference:
345e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(!iterator.Complete());
346750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        current = *reinterpret_cast<char**>(current);
347750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        break;
348750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      case kDescriptorPointerShift:
349e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(!iterator.Complete());
350750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        current += data->pointer_shift_descriptor.byte_offset;
351750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        break;
352750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      case kDescriptorObjectDereference: {
353e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(!iterator.Complete());
354750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        Object* object = CheckedCast<Object>(current);
355750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        int field = data->object_dereference_descriptor.internal_field;
356750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        Object* smi = JSObject::cast(object)->GetInternalField(field);
357e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(smi->IsSmi());
358750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        current = reinterpret_cast<char*>(smi);
359750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        break;
360750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      }
361750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      case kDescriptorBitmaskCompare:
362e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(iterator.Complete());
363750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        return PerformCompare(data->bitmask_compare_descriptor,
364750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                              current,
365e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                              isolate);
366750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      case kDescriptorPointerCompare:
367e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(iterator.Complete());
368750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        return PerformCompare(data->pointer_compare_descriptor,
369750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                              current,
370e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                              isolate);
371750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      case kDescriptorPrimitiveValue:
372e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(iterator.Complete());
373750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        return GetPrimitiveValue(data->primitive_value_descriptor,
374750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                 current,
375e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                 isolate);
376750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    }
377750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
378750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  UNREACHABLE();
379e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return isolate->factory()->undefined_value();
380202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org}
381202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org
382202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org
383ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.orgHandle<FixedArray> JSObject::EnsureWritableFastElements(
384ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    Handle<JSObject> object) {
385e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->HasFastSmiOrObjectElements());
3863484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Isolate* isolate = object->GetIsolate();
3873484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<FixedArray> elems(FixedArray::cast(object->elements()), isolate);
3883484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
3893484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap(
3903484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      elems, isolate->factory()->fixed_array_map());
3913484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  object->set_elements(*writable_elems);
3923484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  isolate->counters()->cow_arrays_converted()->Increment();
3933484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  return writable_elems;
394ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org}
395ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org
396ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org
397e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgMaybeHandle<Object> JSProxy::GetPropertyWithHandler(Handle<JSProxy> proxy,
398e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org                                                    Handle<Object> receiver,
399e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org                                                    Handle<Name> name) {
400e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  Isolate* isolate = proxy->GetIsolate();
401e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
402e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
403e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  if (name->IsSymbol()) return isolate->factory()->undefined_value();
404e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
405e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  Handle<Object> args[] = { receiver, name };
406e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  return CallTrap(
407fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      proxy, "get",  isolate->derived_get_trap(), arraysize(args), args);
408e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org}
409e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
410e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
4118ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orgMaybeHandle<Object> Object::GetPropertyWithAccessor(Handle<Object> receiver,
412e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org                                                    Handle<Name> name,
413e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org                                                    Handle<JSObject> holder,
414e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org                                                    Handle<Object> structure) {
415ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate = name->GetIsolate();
416e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!structure->IsForeign());
41743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // api style callbacks.
418750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (structure->IsAccessorInfo()) {
419d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org    Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure);
420d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org    if (!info->IsCompatibleReceiver(*receiver)) {
4212ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org      Handle<Object> args[2] = { name, receiver };
422ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      THROW_NEW_ERROR(isolate,
423ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                      NewTypeError("incompatible_method_receiver",
424ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                   HandleVector(args, arraysize(args))),
425ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                      Object);
4267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    }
427750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (structure->IsDeclaredAccessorInfo()) {
428e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      return GetDeclaredAccessorProperty(
429e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org          receiver,
430e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org          Handle<DeclaredAccessorInfo>::cast(structure),
431e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org          isolate);
432750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    }
4332ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org
4342ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org    Handle<ExecutableAccessorInfo> data =
4352ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org        Handle<ExecutableAccessorInfo>::cast(structure);
436e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    v8::AccessorNameGetterCallback call_fun =
437e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        v8::ToCData<v8::AccessorNameGetterCallback>(data->getter());
4382ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org    if (call_fun == NULL) return isolate->factory()->undefined_value();
4392ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org
440e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    LOG(isolate, ApiNamedPropertyAccess("load", *holder, *name));
441e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    PropertyCallbackArguments args(isolate, data->data(), *receiver, *holder);
4421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    v8::Handle<v8::Value> result =
443e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        args.Call(call_fun, v8::Utils::ToLocal(name));
4448f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
445ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (result.IsEmpty()) {
4462ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org      return isolate->factory()->undefined_value();
447ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
4482ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org    Handle<Object> return_value = v8::Utils::OpenHandle(*result);
449de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    return_value->VerifyApiCallResultType();
450202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    // Rebox handle before return.
451202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    return handle(*return_value, isolate);
45243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
45343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // __defineGetter__ callback
4552ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org  Handle<Object> getter(Handle<AccessorPair>::cast(structure)->getter(),
4562ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org                        isolate);
4572ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org  if (getter->IsSpecFunction()) {
4582ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org    // TODO(rossberg): nicer would be to cast to some JSCallable here...
459202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    return Object::GetPropertyWithDefinedGetter(
460e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org        receiver, Handle<JSReceiver>::cast(getter));
46143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
4622ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org  // Getter is not a function.
4632ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org  return isolate->factory()->undefined_value();
46443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
46543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
46643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
467d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.orgbool AccessorInfo::IsCompatibleReceiverType(Isolate* isolate,
468d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org                                            Handle<AccessorInfo> info,
469d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org                                            Handle<HeapType> type) {
470d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org  if (!info->HasExpectedReceiverType()) return true;
471d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org  Handle<Map> map = IC::TypeToMap(*type, isolate);
472d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org  if (!map->IsJSObjectMap()) return false;
473d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org  return FunctionTemplateInfo::cast(info->expected_receiver_type())
474d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org      ->IsTemplateFor(*map);
475d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org}
476d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org
477d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org
478474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgMaybeHandle<Object> Object::SetPropertyWithAccessor(
479474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    Handle<Object> receiver, Handle<Name> name, Handle<Object> value,
480474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    Handle<JSObject> holder, Handle<Object> structure, StrictMode strict_mode) {
481e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  Isolate* isolate = name->GetIsolate();
482c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
483e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  // We should never get here to initialize a const with the hole
484e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  // value since a const declaration would conflict with the setter.
485e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!structure->IsForeign());
486e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  if (structure->IsExecutableAccessorInfo()) {
48751e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org    // Don't call executable accessor setters with non-JSObject receivers.
48851e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org    if (!receiver->IsJSObject()) return value;
489e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    // api style callbacks
490d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org    ExecutableAccessorInfo* info = ExecutableAccessorInfo::cast(*structure);
491d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org    if (!info->IsCompatibleReceiver(*receiver)) {
492e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      Handle<Object> args[2] = { name, receiver };
493ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      THROW_NEW_ERROR(isolate,
494ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                      NewTypeError("incompatible_method_receiver",
495ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                   HandleVector(args, arraysize(args))),
496ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                      Object);
497e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    }
498d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org    Object* call_obj = info->setter();
499e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    v8::AccessorNameSetterCallback call_fun =
500e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        v8::ToCData<v8::AccessorNameSetterCallback>(call_obj);
501e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    if (call_fun == NULL) return value;
502e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name));
503d4d66c214e72f4db85c4bccc5561a6d61116b330machenbach@chromium.org    PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder);
504e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    args.Call(call_fun,
505e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org              v8::Utils::ToLocal(name),
506e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org              v8::Utils::ToLocal(value));
507e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
508e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    return value;
509e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  }
510f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
511e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  if (structure->IsAccessorPair()) {
512e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
513e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    if (setter->IsSpecFunction()) {
514e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      // TODO(rossberg): nicer would be to cast to some JSCallable here...
515e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      return SetPropertyWithDefinedSetter(
516e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org          receiver, Handle<JSReceiver>::cast(setter), value);
517e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    } else {
518e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      if (strict_mode == SLOPPY) return value;
519e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      Handle<Object> args[2] = { name, holder };
520ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      THROW_NEW_ERROR(
521ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org          isolate, NewTypeError("no_setter_in_callback", HandleVector(args, 2)),
522ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org          Object);
523e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    }
524e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  }
525e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
526e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  // TODO(dcarney): Handle correctly.
527e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  if (structure->IsDeclaredAccessorInfo()) {
528e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    return value;
529e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  }
530e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
531e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  UNREACHABLE();
532e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  return MaybeHandle<Object>();
533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
536202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.orgMaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
537202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    Handle<Object> receiver,
538202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    Handle<JSReceiver> getter) {
539c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  Isolate* isolate = getter->GetIsolate();
540c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  Debug* debug = isolate->debug();
541e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  // Handle stepping into a getter if step into is active.
542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // TODO(rossberg): should this apply to getters that are function proxies?
543202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  if (debug->StepInActive() && getter->IsJSFunction()) {
544c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    debug->HandleStepIn(
545202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        Handle<JSFunction>::cast(getter), Handle<Object>::null(), 0, false);
546e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  }
547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return Execution::Call(isolate, getter, receiver, 0, NULL, true);
549bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
550bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
551bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
552e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgMaybeHandle<Object> Object::SetPropertyWithDefinedSetter(
553e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    Handle<Object> receiver,
554e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    Handle<JSReceiver> setter,
555e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    Handle<Object> value) {
556e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  Isolate* isolate = setter->GetIsolate();
557e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
558e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  Debug* debug = isolate->debug();
559e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  // Handle stepping into a setter if step into is active.
560e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  // TODO(rossberg): should this apply to getters that are function proxies?
561e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  if (debug->StepInActive() && setter->IsJSFunction()) {
562e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    debug->HandleStepIn(
563e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org        Handle<JSFunction>::cast(setter), Handle<Object>::null(), 0, false);
564e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  }
565e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
566e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  Handle<Object> argv[] = { value };
56751e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org  RETURN_ON_EXCEPTION(isolate, Execution::Call(isolate, setter, receiver,
568fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                                               arraysize(argv), argv, true),
56951e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org                      Object);
570e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  return value;
571e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org}
572e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
573e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
5748ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orgstatic bool FindAllCanReadHolder(LookupIterator* it) {
5758ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  for (; it->IsFound(); it->Next()) {
5761af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org    if (it->state() == LookupIterator::ACCESSOR) {
5778ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org      Handle<Object> accessors = it->GetAccessors();
5788ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org      if (accessors->IsAccessorInfo()) {
5798ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org        if (AccessorInfo::cast(*accessors)->all_can_read()) return true;
5808d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      }
5818d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    }
5828d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
5838d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  return false;
5848d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org}
5858d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
5868d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
5878f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
5888ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org    LookupIterator* it) {
589f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org  Handle<JSObject> checked = it->GetHolder<JSObject>();
5908ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  if (FindAllCanReadHolder(it)) {
591f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org    return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
592f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org                                   it->GetHolder<JSObject>(),
593f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org                                   it->GetAccessors());
59443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
5958ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_GET);
5968ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
5978ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  return it->factory()->undefined_value();
59843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
59943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
60043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
601eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgMaybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck(
6021845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    LookupIterator* it) {
603f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org  Handle<JSObject> checked = it->GetHolder<JSObject>();
604eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  if (FindAllCanReadHolder(it))
605eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    return maybe(it->property_details().attributes());
6061845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS);
607eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(),
608eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                      Maybe<PropertyAttributes>());
609eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  return maybe(ABSENT);
6108d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org}
611870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
612870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
613474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgstatic bool FindAllCanWriteHolder(LookupIterator* it) {
614474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  for (; it->IsFound(); it->Next()) {
6151af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org    if (it->state() == LookupIterator::ACCESSOR) {
616474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      Handle<Object> accessors = it->GetAccessors();
617474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      if (accessors->IsAccessorInfo()) {
618474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        if (AccessorInfo::cast(*accessors)->all_can_write()) return true;
619870a0b67c822d289024711912e2512af01b66c3bager@chromium.org      }
620870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    }
621870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  }
6228d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  return false;
6238d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org}
624870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
6258d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
6268d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orgMaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck(
627474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    LookupIterator* it, Handle<Object> value, StrictMode strict_mode) {
628f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org  Handle<JSObject> checked = it->GetHolder<JSObject>();
629474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (FindAllCanWriteHolder(it)) {
630474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value,
631f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org                                   it->GetHolder<JSObject>(),
632f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org                                   it->GetAccessors(), strict_mode);
6338d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
6348d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
635474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_SET);
636474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
6378d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  return value;
638870a0b67c822d289024711912e2512af01b66c3bager@chromium.org}
639870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
640870a0b67c822d289024711912e2512af01b66c3bager@chromium.org
641528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid JSObject::SetNormalizedProperty(Handle<JSObject> object,
642528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                     Handle<Name> name,
643528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                     Handle<Object> value,
644528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                     PropertyDetails details) {
645e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->HasFastProperties());
646528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<NameDictionary> property_dictionary(object->property_dictionary());
6478e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
6488e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  if (!name->IsUniqueName()) {
649f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    name = object->GetIsolate()->factory()->InternalizeString(
6508e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org        Handle<String>::cast(name));
6518e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  }
6528e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
653f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  int entry = property_dictionary->FindEntry(name);
654750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (entry == NameDictionary::kNotFound) {
655528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<Object> store_value = value;
656528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    if (object->IsGlobalObject()) {
657528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      store_value = object->GetIsolate()->factory()->NewPropertyCell(value);
6582abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    }
6598e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
660f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    property_dictionary = NameDictionary::Add(
661c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        property_dictionary, name, store_value, details);
662528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    object->set_properties(*property_dictionary);
663528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return;
6642abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  }
66506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
666528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  PropertyDetails original_details = property_dictionary->DetailsAt(entry);
66706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  int enumeration_index;
66806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  // Preserve the enumeration index unless the property was deleted.
66906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  if (original_details.IsDeleted()) {
670528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    enumeration_index = property_dictionary->NextEnumerationIndex();
671528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    property_dictionary->SetNextEnumerationIndex(enumeration_index + 1);
67206ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  } else {
67306ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    enumeration_index = original_details.dictionary_index();
674e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(enumeration_index > 0);
67506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  }
67606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
67757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  details = PropertyDetails(
67857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      details.attributes(), details.type(), enumeration_index);
67946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
680528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (object->IsGlobalObject()) {
681528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<PropertyCell> cell(
682528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        PropertyCell::cast(property_dictionary->ValueAt(entry)));
683528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    PropertyCell::SetValueInferType(cell, value);
6842abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    // Please note we have to update the property details.
685528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    property_dictionary->DetailsAtPut(entry, details);
6862abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  } else {
687865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    property_dictionary->SetEntry(entry, name, value, details);
6882abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  }
6892abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
6902abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
6912abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
692ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgHandle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
693ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                  Handle<Name> name,
694ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                  DeleteMode mode) {
695e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->HasFastProperties());
696ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Isolate* isolate = object->GetIsolate();
697ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<NameDictionary> dictionary(object->property_dictionary());
698f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  int entry = dictionary->FindEntry(name);
699750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (entry != NameDictionary::kNotFound) {
7002abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    // If we have a global object set the cell to the hole.
701ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    if (object->IsGlobalObject()) {
7022abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org      PropertyDetails details = dictionary->DetailsAt(entry);
703f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org      if (!details.IsConfigurable()) {
704ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        if (mode != FORCE_DELETION) return isolate->factory()->false_value();
70568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org        // When forced to delete global properties, we have to make a
70668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org        // map change to invalidate any ICs that think they can load
707f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org        // from the non-configurable cell without checking if it contains
70868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org        // the hole value.
709ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
710e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(new_map->is_dictionary_map());
71108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org        JSObject::MigrateToMap(object, new_map);
7122abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org      }
713ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
714528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      Handle<Object> value = isolate->factory()->the_hole_value();
715528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      PropertyCell::SetValueInferType(cell, value);
7162abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org      dictionary->DetailsAtPut(entry, details.AsDeleted());
7172abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    } else {
718865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      Handle<Object> deleted(
719865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org          NameDictionary::DeleteProperty(dictionary, entry, mode));
720ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      if (*deleted == isolate->heap()->true_value()) {
721ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        Handle<NameDictionary> new_properties =
722f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org            NameDictionary::Shrink(dictionary, name);
723ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        object->set_properties(*new_properties);
72404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      }
72504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      return deleted;
7262abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    }
7272abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  }
728ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return isolate->factory()->true_value();
7292abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
7302abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
7312abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
7322bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.combool JSObject::IsDirty() {
7332bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  Object* cons_obj = map()->constructor();
7342bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  if (!cons_obj->IsJSFunction())
7352bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com    return true;
7362bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  JSFunction* fun = JSFunction::cast(cons_obj);
737f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  if (!fun->shared()->IsApiFunction())
7382bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com    return true;
7392bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  // If the object is fully fast case and has the same map it was
7402bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  // created with then no changes can have been made to it.
7412bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  return map() != fun->initial_map()
742830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      || !HasFastObjectElements()
7432bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com      || !HasFastProperties();
7442bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com}
7452bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
7462bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
747202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.orgMaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate,
748202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org                                                   Handle<Object> object,
749202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org                                                   Handle<Object> receiver,
750202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org                                                   uint32_t index) {
7519bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  if (object->IsUndefined()) {
7529bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    // TODO(verwaest): Why is this check here?
7539bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    UNREACHABLE();
7549bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    return isolate->factory()->undefined_value();
7559bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  }
7567c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
7577c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  // Iterate up the prototype chain until an element is found or the null
7587c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  // prototype is encountered.
7599bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  for (PrototypeIterator iter(isolate, object,
7609bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                              object->IsJSProxy() || object->IsJSObject()
7619bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                                  ? PrototypeIterator::START_AT_RECEIVER
7629bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                                  : PrototypeIterator::START_AT_PROTOTYPE);
7639bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org       !iter.IsAtEnd(); iter.Advance()) {
7649bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
7659bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org      return JSProxy::GetElementWithHandler(
7669bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org          Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), receiver,
7679bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org          index);
7687c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    }
769c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
7707c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    // Inline the case for JSObjects. Doing so significantly improves the
7717c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    // performance of fetching elements where checking the prototype chain is
7727c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    // necessary.
7739bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    Handle<JSObject> js_object =
7749bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
7757c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
7767c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    // Check access rights if needed.
7777c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    if (js_object->IsAccessCheckNeeded()) {
778c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) {
779c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET);
7808496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
781b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org        return isolate->factory()->undefined_value();
7827c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org      }
783c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
784c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
7857c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    if (js_object->HasIndexedInterceptor()) {
786b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org      return JSObject::GetElementWithInterceptor(js_object, receiver, index);
7877c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    }
7887c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
789b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org    if (js_object->elements() != isolate->heap()->empty_fixed_array()) {
790202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      Handle<Object> result;
791202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      ASSIGN_RETURN_ON_EXCEPTION(
792202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org          isolate, result,
793202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org          js_object->GetElementsAccessor()->Get(receiver, js_object, index),
794202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org          Object);
795b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org      if (!result->IsTheHole()) return result;
796c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
79749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  }
79849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
799b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  return isolate->factory()->undefined_value();
80043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
80143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
80243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8039bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.orgMap* Object::GetRootMap(Isolate* isolate) {
804e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  DisallowHeapAllocation no_alloc;
805c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (IsSmi()) {
8068432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    Context* context = isolate->context()->native_context();
8079bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    return context->number_function()->initial_map();
808c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
809c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
810c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  HeapObject* heap_object = HeapObject::cast(this);
811c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
8127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // The object is either a number, a string, a boolean,
8137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // a real JS object, or a Harmony proxy.
814d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  if (heap_object->IsJSReceiver()) {
8159bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    return heap_object->map();
816c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
8178432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Context* context = isolate->context()->native_context();
81843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
819c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (heap_object->IsHeapNumber()) {
8209bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    return context->number_function()->initial_map();
821c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
822c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (heap_object->IsString()) {
8239bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    return context->string_function()->initial_map();
824c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
825f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (heap_object->IsSymbol()) {
8269bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    return context->symbol_function()->initial_map();
827f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
828c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (heap_object->IsBoolean()) {
8299bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    return context->boolean_function()->initial_map();
83043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
8319bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  return isolate->heap()->null_value()->map();
832e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org}
833e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
834e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
835057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgObject* Object::GetHash() {
836750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // The object is either a number, a name, an odd-ball,
837394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // a real JS object, or a Harmony proxy.
838394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (IsNumber()) {
839394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    uint32_t hash = ComputeLongHash(double_to_uint64(Number()));
840394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return Smi::FromInt(hash & Smi::kMaxValue);
841394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
8424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (IsName()) {
8434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    uint32_t hash = Name::cast(this)->Hash();
844394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return Smi::FromInt(hash);
845394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
846394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (IsOddball()) {
847394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    uint32_t hash = Oddball::cast(this)->to_string()->Hash();
848394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return Smi::FromInt(hash);
849394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
850394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
851e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsJSReceiver());
852057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  return JSReceiver::cast(this)->GetIdentityHash();
853057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org}
854057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
855057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
8563c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.orgHandle<Smi> Object::GetOrCreateHash(Isolate* isolate, Handle<Object> object) {
857057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Handle<Object> hash(object->GetHash(), isolate);
8583c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  if (hash->IsSmi()) return Handle<Smi>::cast(hash);
859057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
860e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->IsJSReceiver());
861057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  return JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver>::cast(object));
862394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
863394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
864394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
865394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.combool Object::SameValue(Object* other) {
866394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (other == this) return true;
867394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
868750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // The object is either a number, a name, an odd-ball,
869394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // a real JS object, or a Harmony proxy.
870394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (IsNumber() && other->IsNumber()) {
871394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    double this_value = Number();
872394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    double other_value = other->Number();
8733d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    bool equal = this_value == other_value;
8743d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    // SameValue(NaN, NaN) is true.
8753d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    if (!equal) return std::isnan(this_value) && std::isnan(other_value);
8763d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    // SameValue(0.0, -0.0) is false.
8773d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    return (this_value != 0) || ((1 / this_value) == (1 / other_value));
878394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
879394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (IsString() && other->IsString()) {
880394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return String::cast(this)->Equals(String::cast(other));
881394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
882394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return false;
883394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
884394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
885394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
88679d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.orgbool Object::SameValueZero(Object* other) {
88779d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  if (other == this) return true;
88879d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org
88979d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  // The object is either a number, a name, an odd-ball,
89079d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  // a real JS object, or a Harmony proxy.
89179d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  if (IsNumber() && other->IsNumber()) {
89279d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org    double this_value = Number();
89379d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org    double other_value = other->Number();
89479d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org    // +0 == -0 is true
89579d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org    return this_value == other_value
89679d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org        || (std::isnan(this_value) && std::isnan(other_value));
89779d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  }
89879d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  if (IsString() && other->IsString()) {
89979d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org    return String::cast(this)->Equals(String::cast(other));
90079d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  }
90179d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org  return false;
90279d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org}
90379d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org
90479d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org
905023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.orgvoid Object::ShortPrint(FILE* out) {
906f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  OFStream os(out);
907f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << Brief(this);
90843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
90943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
91043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
91143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Object::ShortPrint(StringStream* accumulator) {
912f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  OStringStream os;
913f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << Brief(this);
914f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  accumulator->Add(os.c_str());
91543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
91643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
91743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
918f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgOStream& operator<<(OStream& os, const Brief& v) {
919f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  if (v.value->IsSmi()) {
920f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    Smi::cast(v.value)->SmiPrint(os);
921f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  } else {
922f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    // TODO(svenpanne) Const-correct HeapObjectShortPrint!
923f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    HeapObject* obj = const_cast<HeapObject*>(HeapObject::cast(v.value));
924f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    obj->HeapObjectShortPrint(os);
925f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  }
926f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  return os;
92743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
92843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
92943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
930f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgvoid Smi::SmiPrint(OStream& os) const {  // NOLINT
931f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << value();
93243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
93343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
93443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
93543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Should a word be prefixed by 'a' or 'an' in order to read naturally in
93643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// English?  Returns false for non-ASCII or words that don't start with
93743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// a capital letter.  The a/an rule follows pronunciation in English.
93843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// We don't use the BBC's overcorrect "an historic occasion" though if
93943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// you speak a dialect you may well say "an 'istoric occasion".
94043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic bool AnWord(String* str) {
941bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (str->length() == 0) return false;  // A nothing.
942bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int c0 = str->Get(0);
943bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int c1 = str->length() > 1 ? str->Get(1) : 0;
94443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (c0 == 'U') {
94543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (c1 > 'Z') {
946870a0b67c822d289024711912e2512af01b66c3bager@chromium.org      return true;  // An Umpire, but a UTF8String, a U.
94743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
94843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (c0 == 'A' || c0 == 'E' || c0 == 'I' || c0 == 'O') {
949870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    return true;    // An Ape, an ABCBook.
95043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if ((c1 == 0 || (c1 >= 'A' && c1 <= 'Z')) &&
95143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen           (c0 == 'F' || c0 == 'H' || c0 == 'M' || c0 == 'N' || c0 == 'R' ||
95243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            c0 == 'S' || c0 == 'X')) {
953870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    return true;    // An MP3File, an M.
95443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
95543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return false;
95643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
95743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
95843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9599e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgHandle<String> String::SlowFlatten(Handle<ConsString> cons,
9609e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                   PretenureFlag pretenure) {
961e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(AllowHeapAllocation::IsAllowed());
962e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(cons->second()->length() != 0);
9639e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Isolate* isolate = cons->GetIsolate();
9649e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  int length = cons->length();
9659e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  PretenureFlag tenure = isolate->heap()->InNewSpace(*cons) ? pretenure
9669e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                                            : TENURED;
9679e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<SeqString> result;
9689e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  if (cons->IsOneByteRepresentation()) {
9699e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Handle<SeqOneByteString> flat = isolate->factory()->NewRawOneByteString(
9709e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org        length, tenure).ToHandleChecked();
9719e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    DisallowHeapAllocation no_gc;
9729e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    WriteToFlat(*cons, flat->GetChars(), 0, length);
9739e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    result = flat;
9749e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  } else {
9759e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Handle<SeqTwoByteString> flat = isolate->factory()->NewRawTwoByteString(
9769e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org        length, tenure).ToHandleChecked();
9779e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    DisallowHeapAllocation no_gc;
9789e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    WriteToFlat(*cons, flat->GetChars(), 0, length);
9799e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    result = flat;
9809e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  }
9819e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  cons->set_first(*result);
9829e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  cons->set_second(isolate->heap()->empty_string());
983e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(result->IsFlat());
9849e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  return result;
9859e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org}
9869e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org
9879e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org
98843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9896f10e41fef1524c70846d970268de222e41c594cager@chromium.orgbool String::MakeExternal(v8::String::ExternalStringResource* resource) {
99032d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org  // Externalizing twice leaks the external resource, so it's
9915ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // prohibited by the API.
992e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!this->IsExternalString());
993e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org#ifdef ENABLE_SLOW_DCHECKS
9943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  if (FLAG_enable_slow_asserts) {
9956f10e41fef1524c70846d970268de222e41c594cager@chromium.org    // Assert that the resource and the string are equivalent.
996e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(static_cast<size_t>(this->length()) == resource->length());
997720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org    ScopedVector<uc16> smart_chars(this->length());
998720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org    String::WriteToFlat(this, smart_chars.start(), 0, this->length());
999e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(memcmp(smart_chars.start(),
10006f10e41fef1524c70846d970268de222e41c594cager@chromium.org                  resource->data(),
1001720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org                  resource->length() * sizeof(smart_chars[0])) == 0);
10026f10e41fef1524c70846d970268de222e41c594cager@chromium.org  }
10036f10e41fef1524c70846d970268de222e41c594cager@chromium.org#endif  // DEBUG
10046f10e41fef1524c70846d970268de222e41c594cager@chromium.org  int size = this->Size();  // Byte size of the original string.
100531c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  // Abort if size does not allow in-place conversion.
100631c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  if (size < ExternalString::kShortSize) return false;
100731c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  Heap* heap = GetHeap();
10082c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  bool is_one_byte = this->IsOneByteRepresentation();
10094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  bool is_internalized = this->IsInternalizedString();
10106f10e41fef1524c70846d970268de222e41c594cager@chromium.org
10118297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  // Morph the string to an external string by replacing the map and
10122c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  // reinitializing the fields.  This won't work if the space the existing
10132c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  // string occupies is too small for a regular  external string.
10142c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  // Instead, we resort to a short external string instead, omitting
10158297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  // the field caching the address of the backing store.  When we encounter
10168297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  // short external strings in generated code, we need to bailout to runtime.
101763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  Map* new_map;
10182c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  if (size < ExternalString::kSize) {
101963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org    new_map = is_internalized
10202c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        ? (is_one_byte
10212c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org           ? heap->short_external_internalized_string_with_one_byte_data_map()
10222c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org           : heap->short_external_internalized_string_map())
10232c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        : (is_one_byte ? heap->short_external_string_with_one_byte_data_map()
10242c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                       : heap->short_external_string_map());
10251b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  } else {
102663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org    new_map = is_internalized
10272c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        ? (is_one_byte
10282c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org           ? heap->external_internalized_string_with_one_byte_data_map()
10292c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org           : heap->external_internalized_string_map())
10302c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        : (is_one_byte ? heap->external_string_with_one_byte_data_map()
10312c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                       : heap->external_string_map());
10321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
103363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
103463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  // Byte size of the external String object.
103563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  int new_size = this->SizeFromMap(new_map);
103663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  heap->CreateFillerObjectAt(this->address() + new_size, size - new_size);
103763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
103863a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  // We are storing the new map using release store after creating a filler for
103963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  // the left-over space to avoid races with the sweeper thread.
104063a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  this->synchronized_set_map(new_map);
104163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
10426f10e41fef1524c70846d970268de222e41c594cager@chromium.org  ExternalTwoByteString* self = ExternalTwoByteString::cast(this);
10436f10e41fef1524c70846d970268de222e41c594cager@chromium.org  self->set_resource(resource);
10444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (is_internalized) self->Hash();  // Force regeneration of the hash value.
10456f10e41fef1524c70846d970268de222e41c594cager@chromium.org
10465697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  heap->AdjustLiveBytes(this->address(), new_size - size, Heap::FROM_MUTATOR);
10476f10e41fef1524c70846d970268de222e41c594cager@chromium.org  return true;
10486f10e41fef1524c70846d970268de222e41c594cager@chromium.org}
10496f10e41fef1524c70846d970268de222e41c594cager@chromium.org
10506f10e41fef1524c70846d970268de222e41c594cager@chromium.org
10512c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgbool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
105231c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  // Externalizing twice leaks the external resource, so it's
105331c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  // prohibited by the API.
105431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  DCHECK(!this->IsExternalString());
1055e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org#ifdef ENABLE_SLOW_DCHECKS
10563811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  if (FLAG_enable_slow_asserts) {
10576f10e41fef1524c70846d970268de222e41c594cager@chromium.org    // Assert that the resource and the string are equivalent.
1058e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(static_cast<size_t>(this->length()) == resource->length());
1059dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    if (this->IsTwoByteRepresentation()) {
1060dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      ScopedVector<uint16_t> smart_chars(this->length());
1061dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      String::WriteToFlat(this, smart_chars.start(), 0, this->length());
1062e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(String::IsOneByte(smart_chars.start(), this->length()));
1063dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    }
1064720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org    ScopedVector<char> smart_chars(this->length());
1065720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org    String::WriteToFlat(this, smart_chars.start(), 0, this->length());
1066e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(memcmp(smart_chars.start(),
10676f10e41fef1524c70846d970268de222e41c594cager@chromium.org                  resource->data(),
1068720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org                  resource->length() * sizeof(smart_chars[0])) == 0);
10696f10e41fef1524c70846d970268de222e41c594cager@chromium.org  }
10706f10e41fef1524c70846d970268de222e41c594cager@chromium.org#endif  // DEBUG
10716f10e41fef1524c70846d970268de222e41c594cager@chromium.org  int size = this->Size();  // Byte size of the original string.
107231c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  // Abort if size does not allow in-place conversion.
107331c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  if (size < ExternalString::kShortSize) return false;
107431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  Heap* heap = GetHeap();
10754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  bool is_internalized = this->IsInternalizedString();
10766f10e41fef1524c70846d970268de222e41c594cager@chromium.org
10778297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  // Morph the string to an external string by replacing the map and
10782c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  // reinitializing the fields.  This won't work if the space the existing
10792c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  // string occupies is too small for a regular  external string.
10802c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  // Instead, we resort to a short external string instead, omitting
10818297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  // the field caching the address of the backing store.  When we encounter
10828297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  // short external strings in generated code, we need to bailout to runtime.
108363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  Map* new_map;
10842c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  if (size < ExternalString::kSize) {
108563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org    new_map = is_internalized
10862c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                  ? heap->short_external_one_byte_internalized_string_map()
10872c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                  : heap->short_external_one_byte_string_map();
10888297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  } else {
108963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org    new_map = is_internalized
10902c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                  ? heap->external_one_byte_internalized_string_map()
10912c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                  : heap->external_one_byte_string_map();
10921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
109363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
109463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  // Byte size of the external String object.
109563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  int new_size = this->SizeFromMap(new_map);
109663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  heap->CreateFillerObjectAt(this->address() + new_size, size - new_size);
109763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
109863a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  // We are storing the new map using release store after creating a filler for
109963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  // the left-over space to avoid races with the sweeper thread.
110063a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  this->synchronized_set_map(new_map);
110163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
11022c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  ExternalOneByteString* self = ExternalOneByteString::cast(this);
11036f10e41fef1524c70846d970268de222e41c594cager@chromium.org  self->set_resource(resource);
11044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (is_internalized) self->Hash();  // Force regeneration of the hash value.
11056f10e41fef1524c70846d970268de222e41c594cager@chromium.org
11065697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  heap->AdjustLiveBytes(this->address(), new_size - size, Heap::FROM_MUTATOR);
11076f10e41fef1524c70846d970268de222e41c594cager@chromium.org  return true;
11086f10e41fef1524c70846d970268de222e41c594cager@chromium.org}
11096f10e41fef1524c70846d970268de222e41c594cager@chromium.org
11106f10e41fef1524c70846d970268de222e41c594cager@chromium.org
111143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid String::StringShortPrint(StringStream* accumulator) {
1112bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int len = length();
1113ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  if (len > kMaxShortPrintLength) {
111443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    accumulator->Add("<Very long string[%u]>", len);
111543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
111643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
111743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
111843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!LooksValid()) {
111943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    accumulator->Add("<Invalid String>");
112043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
112143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
112243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11234cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ConsStringIteratorOp op;
11244cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  StringCharacterStream stream(this, &op);
112543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
112643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool truncated = false;
11277276f14ca716596e0a0d17539516370c1f453847kasper.lund  if (len > kMaxShortPrintLength) {
11287276f14ca716596e0a0d17539516370c1f453847kasper.lund    len = kMaxShortPrintLength;
112943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    truncated = true;
113043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
11312c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  bool one_byte = true;
113243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < len; i++) {
11334cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    uint16_t c = stream.GetNext();
113443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
113543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (c < 32 || c >= 127) {
11362c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      one_byte = false;
113743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
113843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
11394cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  stream.Reset(this);
11402c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  if (one_byte) {
1141bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    accumulator->Add("<String[%u]: ", length());
114243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (int i = 0; i < len; i++) {
11434cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      accumulator->Put(static_cast<char>(stream.GetNext()));
114443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
114543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    accumulator->Put('>');
114643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
114743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Backslash indicates that the string contains control
114843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // characters and that backslashes are therefore escaped.
1149bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    accumulator->Add("<String[%u]\\: ", length());
115043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (int i = 0; i < len; i++) {
11514cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      uint16_t c = stream.GetNext();
115243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (c == '\n') {
115343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        accumulator->Add("\\n");
115443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else if (c == '\r') {
115543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        accumulator->Add("\\r");
115643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else if (c == '\\') {
115743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        accumulator->Add("\\\\");
115843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else if (c < 32 || c > 126) {
115943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        accumulator->Add("\\x%02x", c);
116043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
11614cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        accumulator->Put(static_cast<char>(c));
116243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
116343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
116443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (truncated) {
116543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      accumulator->Put('.');
116643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      accumulator->Put('.');
116743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      accumulator->Put('.');
116843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
116943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    accumulator->Put('>');
117043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
117143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return;
117243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
117343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1175f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgvoid String::PrintUC16(OStream& os, int start, int end) {  // NOLINT
1176f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  if (end < 0) end = length();
1177f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  ConsStringIteratorOp op;
1178f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  StringCharacterStream stream(this, &op, start);
1179f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  for (int i = start; i < end && stream.HasMore(); i++) {
1180f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << AsUC16(stream.GetNext());
1181f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  }
1182f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org}
1183f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
1184f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
118543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid JSObject::JSObjectShortPrint(StringStream* accumulator) {
118643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (map()->instance_type()) {
118743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case JS_ARRAY_TYPE: {
1188830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      double length = JSArray::cast(this)->length()->IsUndefined()
1189830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org          ? 0
1190830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org          : JSArray::cast(this)->length()->Number();
11914efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      accumulator->Add("<JS Array[%u]>", static_cast<uint32_t>(length));
119243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
119343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
11947c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    case JS_WEAK_MAP_TYPE: {
1195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      accumulator->Add("<JS WeakMap>");
11967c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org      break;
11977c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    }
1198ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    case JS_WEAK_SET_TYPE: {
1199ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      accumulator->Add("<JS WeakSet>");
1200ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      break;
1201ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    }
1202236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    case JS_REGEXP_TYPE: {
1203236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      accumulator->Add("<JS RegExp>");
1204236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      break;
1205236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    }
120643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case JS_FUNCTION_TYPE: {
1207906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      JSFunction* function = JSFunction::cast(this);
1208906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      Object* fun_name = function->shared()->DebugName();
120943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      bool printed = false;
121043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (fun_name->IsString()) {
121143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        String* str = String::cast(fun_name);
121243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (str->length() > 0) {
121343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          accumulator->Add("<JS Function ");
121443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          accumulator->Put(str);
121543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          printed = true;
121643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
121743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
121843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (!printed) {
1219906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org        accumulator->Add("<JS Function");
122043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1221906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      accumulator->Add(" (SharedFunctionInfo %p)",
1222906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org                       reinterpret_cast<void*>(function->shared()));
1223906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      accumulator->Put('>');
122443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
122543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1226e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    case JS_GENERATOR_OBJECT_TYPE: {
1227e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      accumulator->Add("<JS Generator>");
1228e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      break;
1229e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
12308e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    case JS_MODULE_TYPE: {
12318e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      accumulator->Add("<JS Module>");
12328e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      break;
12338e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    }
123443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // All other JSObjects are rather similar to each other (JSObject,
12355a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    // JSGlobalProxy, JSGlobalObject, JSUndetectableObject, JSValue).
123643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    default: {
1237c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      Map* map_of_this = map();
1238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Heap* heap = GetHeap();
1239c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      Object* constructor = map_of_this->constructor();
124043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      bool printed = false;
124143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (constructor->IsHeapObject() &&
1242ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          !heap->Contains(HeapObject::cast(constructor))) {
124343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        accumulator->Add("!!!INVALID CONSTRUCTOR!!!");
124443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
12455a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org        bool global_object = IsJSGlobalProxy();
124643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (constructor->IsJSFunction()) {
1247ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          if (!heap->Contains(JSFunction::cast(constructor)->shared())) {
124843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!");
124943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          } else {
125043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            Object* constructor_name =
125143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                JSFunction::cast(constructor)->shared()->name();
125243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            if (constructor_name->IsString()) {
125343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen              String* str = String::cast(constructor_name);
125443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen              if (str->length() > 0) {
125543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                bool vowel = AnWord(str);
125643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                accumulator->Add("<%sa%s ",
12575a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                       global_object ? "Global Object: " : "",
125843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                       vowel ? "n" : "");
125943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                accumulator->Put(str);
1260b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                accumulator->Add(" with %smap %p",
1261906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org                    map_of_this->is_deprecated() ? "deprecated " : "",
1262906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org                    map_of_this);
126343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                printed = true;
126443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen              }
126543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            }
126643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          }
126743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
126843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (!printed) {
126943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          accumulator->Add("<JS %sObject", global_object ? "Global " : "");
127043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
127143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
127243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (IsJSValue()) {
127343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        accumulator->Add(" value = ");
127443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        JSValue::cast(this)->value()->ShortPrint(accumulator);
127543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
127643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      accumulator->Put('>');
127743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
127843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
127943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
128043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
128143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
128243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1283394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid JSObject::PrintElementsTransition(
12849b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    FILE* file, Handle<JSObject> object,
12859b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
12869b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    ElementsKind to_kind, Handle<FixedArrayBase> to_elements) {
1287394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (from_kind != to_kind) {
1288f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    OFStream os(file);
1289f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "elements transition [" << ElementsKindToString(from_kind) << " -> "
1290f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org       << ElementsKindToString(to_kind) << "] in ";
12919b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    JavaScriptFrame::PrintTop(object->GetIsolate(), file, false, true);
1292394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    PrintF(file, " for ");
12939b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    object->ShortPrint(file);
1294394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    PrintF(file, " from ");
1295394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    from_elements->ShortPrint(file);
1296394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    PrintF(file, " to ");
1297394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    to_elements->ShortPrint(file);
1298394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    PrintF(file, "\n");
1299394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
1300394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1301394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1302394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
130332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.orgvoid Map::PrintGeneralization(FILE* file,
13049259716434187c932704601f700375e53d865de8rossberg@chromium.org                              const char* reason,
130532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org                              int modify_index,
130632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org                              int split,
130732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org                              int descriptors,
13089259716434187c932704601f700375e53d865de8rossberg@chromium.org                              bool constant_to_field,
130932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org                              Representation old_representation,
1310e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                              Representation new_representation,
1311e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                              HeapType* old_field_type,
1312e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                              HeapType* new_field_type) {
1313d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  OFStream os(file);
1314d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  os << "[generalizing ";
131532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  constructor_name()->PrintOn(file);
1316d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  os << "] ";
1317f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Name* name = instance_descriptors()->GetKey(modify_index);
1318f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (name->IsString()) {
1319f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    String::cast(name)->PrintOn(file);
1320f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  } else {
1321d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    os << "{symbol " << static_cast<void*>(name) << "}";
1322f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
1323d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  os << ":";
13249259716434187c932704601f700375e53d865de8rossberg@chromium.org  if (constant_to_field) {
1325d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    os << "c";
13269259716434187c932704601f700375e53d865de8rossberg@chromium.org  } else {
1327d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    os << old_representation.Mnemonic() << "{";
1328d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    old_field_type->PrintTo(os, HeapType::SEMANTIC_DIM);
1329d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    os << "}";
1330d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  }
1331d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  os << "->" << new_representation.Mnemonic() << "{";
1332d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  new_field_type->PrintTo(os, HeapType::SEMANTIC_DIM);
1333d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  os << "} (";
13349259716434187c932704601f700375e53d865de8rossberg@chromium.org  if (strlen(reason) > 0) {
1335d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    os << reason;
13369259716434187c932704601f700375e53d865de8rossberg@chromium.org  } else {
1337d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    os << "+" << (descriptors - split) << " maps";
13389259716434187c932704601f700375e53d865de8rossberg@chromium.org  }
1339d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  os << ") [";
134032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  JavaScriptFrame::PrintTop(GetIsolate(), file, false, true);
1341d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  os << "]\n";
134232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org}
134332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
134432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
134532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.orgvoid JSObject::PrintInstanceMigration(FILE* file,
134632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org                                      Map* original_map,
134732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org                                      Map* new_map) {
134832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  PrintF(file, "[migrating ");
134932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  map()->constructor_name()->PrintOn(file);
135032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  PrintF(file, "] ");
135132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  DescriptorArray* o = original_map->instance_descriptors();
135232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  DescriptorArray* n = new_map->instance_descriptors();
135332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) {
135432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    Representation o_r = o->GetDetails(i).representation();
135532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    Representation n_r = n->GetDetails(i).representation();
135632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    if (!o_r.Equals(n_r)) {
135732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      String::cast(o->GetKey(i))->PrintOn(file);
135832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic());
135932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    } else if (o->GetDetails(i).type() == CONSTANT &&
136032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org               n->GetDetails(i).type() == FIELD) {
136132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      Name* name = o->GetKey(i);
136232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      if (name->IsString()) {
136332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org        String::cast(name)->PrintOn(file);
136432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      } else {
1365f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        PrintF(file, "{symbol %p}", static_cast<void*>(name));
136632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      }
136732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      PrintF(file, " ");
136832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    }
136932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  }
137032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  PrintF(file, "\n");
137132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org}
137232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
137332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
1374f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgvoid HeapObject::HeapObjectShortPrint(OStream& os) {  // NOLINT
1375ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = GetHeap();
1376ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!heap->Contains(this)) {
1377f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "!!!INVALID POINTER!!!";
137843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
137943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1380ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!heap->Contains(map())) {
1381f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "!!!INVALID MAP!!!";
138243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
138343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
138443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1385f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << this << " ";
138643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
138743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (IsString()) {
1388f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    HeapStringAllocator allocator;
1389f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    StringStream accumulator(&allocator);
1390f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    String::cast(this)->StringShortPrint(&accumulator);
1391f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << accumulator.ToCString().get();
139243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
139343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
139443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (IsJSObject()) {
1395f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    HeapStringAllocator allocator;
1396f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    StringStream accumulator(&allocator);
1397f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    JSObject::cast(this)->JSObjectShortPrint(&accumulator);
1398f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << accumulator.ToCString().get();
139943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
140043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
140143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (map()->instance_type()) {
140243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case MAP_TYPE:
1403f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "<Map(elements=" << Map::cast(this)->elements_kind() << ")>";
140443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
140543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case FIXED_ARRAY_TYPE:
1406f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "<FixedArray[" << FixedArray::cast(this)->length() << "]>";
140743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
1408394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    case FIXED_DOUBLE_ARRAY_TYPE:
1409f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "<FixedDoubleArray[" << FixedDoubleArray::cast(this)->length()
1410f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org         << "]>";
1411394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      break;
141243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case BYTE_ARRAY_TYPE:
1413f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "<ByteArray[" << ByteArray::cast(this)->length() << "]>";
141443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
1415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    case FREE_SPACE_TYPE:
1416f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "<FreeSpace[" << FreeSpace::cast(this)->Size() << "]>";
14175c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      break;
1418f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org#define TYPED_ARRAY_SHORT_PRINT(Type, type, TYPE, ctype, size)                \
1419f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  case EXTERNAL_##TYPE##_ARRAY_TYPE:                                          \
1420f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "<External" #Type "Array["                                          \
1421f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org       << External##Type##Array::cast(this)->length() << "]>";                \
1422f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    break;                                                                    \
1423f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  case FIXED_##TYPE##_ARRAY_TYPE:                                             \
1424f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "<Fixed" #Type "Array[" << Fixed##Type##Array::cast(this)->length() \
1425f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org       << "]>";                                                               \
1426f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    break;
1427af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
1428af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(TYPED_ARRAY_SHORT_PRINT)
1429af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef TYPED_ARRAY_SHORT_PRINT
1430af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
1431906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    case SHARED_FUNCTION_INFO_TYPE: {
1432906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      SharedFunctionInfo* shared = SharedFunctionInfo::cast(this);
1433906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      SmartArrayPointer<char> debug_name =
1434906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org          shared->DebugName()->ToCString();
1435906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      if (debug_name[0] != 0) {
1436f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << "<SharedFunctionInfo " << debug_name.get() << ">";
1437906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      } else {
1438f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << "<SharedFunctionInfo>";
1439906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      }
144043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
1441906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    }
144231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org    case JS_MESSAGE_OBJECT_TYPE:
1443f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "<JSMessageObject>";
144431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org      break;
144543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define MAKE_STRUCT_CASE(NAME, Name, name) \
144643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  case NAME##_TYPE:                        \
1447f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "<" #Name ">";                   \
144843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    break;
144943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  STRUCT_LIST(MAKE_STRUCT_CASE)
145043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef MAKE_STRUCT_CASE
14517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case CODE_TYPE: {
14527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Code* code = Code::cast(this);
14537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      os << "<Code: " << Code::Kind2String(code->kind()) << ">";
145443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
14557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
145643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case ODDBALL_TYPE: {
1457f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      if (IsUndefined()) {
1458f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << "<undefined>";
1459f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      } else if (IsTheHole()) {
1460f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << "<the hole>";
1461f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      } else if (IsNull()) {
1462f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << "<null>";
1463f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      } else if (IsTrue()) {
1464f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << "<true>";
1465f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      } else if (IsFalse()) {
1466f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << "<false>";
1467f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      } else {
1468f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << "<Odd Oddball>";
1469f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      }
147043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
147143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1472f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    case SYMBOL_TYPE: {
1473f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      Symbol* symbol = Symbol::cast(this);
1474f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "<Symbol: " << symbol->Hash();
1475f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      if (!symbol->name()->IsUndefined()) {
1476f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << " ";
1477f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        HeapStringAllocator allocator;
1478f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        StringStream accumulator(&allocator);
1479f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        String::cast(symbol->name())->StringShortPrint(&accumulator);
1480f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << accumulator.ToCString().get();
1481f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      }
1482f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << ">";
14834a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      break;
1484f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    }
1485f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    case HEAP_NUMBER_TYPE: {
1486f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "<Number: ";
1487f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      HeapNumber::cast(this)->HeapNumberPrint(os);
1488f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << ">";
148943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
1490f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    }
1491f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    case MUTABLE_HEAP_NUMBER_TYPE: {
1492f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "<MutableNumber: ";
1493f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      HeapNumber::cast(this)->HeapNumberPrint(os);
1494f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << '>';
149558a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org      break;
1496f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    }
149734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    case JS_PROXY_TYPE:
1498f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "<JSProxy>";
149934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      break;
150034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    case JS_FUNCTION_PROXY_TYPE:
1501f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "<JSFunctionProxy>";
150234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      break;
1503ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    case FOREIGN_TYPE:
1504f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "<Foreign>";
150543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
1506f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    case CELL_TYPE: {
1507f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "Cell for ";
1508f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      HeapStringAllocator allocator;
1509f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      StringStream accumulator(&allocator);
1510f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      Cell::cast(this)->value()->ShortPrint(&accumulator);
1511f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << accumulator.ToCString().get();
151241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      break;
1513f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    }
1514f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    case PROPERTY_CELL_TYPE: {
1515f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "PropertyCell for ";
1516f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      HeapStringAllocator allocator;
1517f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      StringStream accumulator(&allocator);
1518f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      PropertyCell::cast(this)->value()->ShortPrint(&accumulator);
1519f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << accumulator.ToCString().get();
15202abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org      break;
1521f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    }
152243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    default:
1523f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "<Other heap object (" << map()->instance_type() << ")>";
152443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
152543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
152643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
152743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
152843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
152943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid HeapObject::Iterate(ObjectVisitor* v) {
153043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Handle header
153143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  IteratePointer(v, kMapOffset);
153243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Handle object body
153343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Map* m = map();
153443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  IterateBody(m->instance_type(), SizeFromMap(m), v);
153543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
153643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
153743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
153843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid HeapObject::IterateBody(InstanceType type, int object_size,
153943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                             ObjectVisitor* v) {
154043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Avoiding <Type>::cast(this) because it accesses the map pointer field.
154143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // During GC, the map pointer field is encoded.
154243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (type < FIRST_NONSTRING_TYPE) {
154343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    switch (type & kStringRepresentationMask) {
154443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      case kSeqStringTag:
154543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
154643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      case kConsStringTag:
1547ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org        ConsString::BodyDescriptor::IterateBody(this, v);
154843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
15494668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      case kSlicedStringTag:
15504668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org        SlicedString::BodyDescriptor::IterateBody(this, v);
15514668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org        break;
1552c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      case kExternalStringTag:
1553e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org        if ((type & kStringEncodingMask) == kOneByteStringTag) {
15542c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org          reinterpret_cast<ExternalOneByteString*>(this)
15552c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org              ->ExternalOneByteStringIterateBody(v);
1556c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        } else {
1557c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org          reinterpret_cast<ExternalTwoByteString*>(this)->
1558c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org              ExternalTwoByteStringIterateBody(v);
1559c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        }
156043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
156143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
156243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
156343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
156443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
156543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  switch (type) {
156643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case FIXED_ARRAY_TYPE:
1567ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      FixedArray::BodyDescriptor::IterateBody(this, object_size, v);
156843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
1569a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    case CONSTANT_POOL_ARRAY_TYPE:
1570a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      reinterpret_cast<ConstantPoolArray*>(this)->ConstantPoolIterateBody(v);
1571a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      break;
15726d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    case FIXED_DOUBLE_ARRAY_TYPE:
15736d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      break;
157443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case JS_OBJECT_TYPE:
15753291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
1576e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    case JS_GENERATOR_OBJECT_TYPE:
1577ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    case JS_MODULE_TYPE:
157843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case JS_VALUE_TYPE:
15794efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    case JS_DATE_TYPE:
158043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case JS_ARRAY_TYPE:
1581f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    case JS_ARRAY_BUFFER_TYPE:
1582e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    case JS_TYPED_ARRAY_TYPE:
15831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    case JS_DATA_VIEW_TYPE:
1584394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    case JS_SET_TYPE:
1585394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    case JS_MAP_TYPE:
15864ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    case JS_SET_ITERATOR_TYPE:
15874ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    case JS_MAP_ITERATOR_TYPE:
15887c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    case JS_WEAK_MAP_TYPE:
1589ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    case JS_WEAK_SET_TYPE:
1590236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    case JS_REGEXP_TYPE:
15915a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    case JS_GLOBAL_PROXY_TYPE:
159243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case JS_GLOBAL_OBJECT_TYPE:
159343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case JS_BUILTINS_OBJECT_TYPE:
159431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org    case JS_MESSAGE_OBJECT_TYPE:
1595ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      JSObject::BodyDescriptor::IterateBody(this, object_size, v);
159643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
1597145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com    case JS_FUNCTION_TYPE:
1598145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com      reinterpret_cast<JSFunction*>(this)
1599145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com          ->JSFunctionIterateBody(object_size, v);
1600145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com      break;
160143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case ODDBALL_TYPE:
1602ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      Oddball::BodyDescriptor::IterateBody(this, v);
160343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
16047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    case JS_PROXY_TYPE:
16057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      JSProxy::BodyDescriptor::IterateBody(this, v);
16067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      break;
160734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    case JS_FUNCTION_PROXY_TYPE:
160834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      JSFunctionProxy::BodyDescriptor::IterateBody(this, v);
160934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      break;
1610ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    case FOREIGN_TYPE:
1611ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      reinterpret_cast<Foreign*>(this)->ForeignIterateBody(v);
161243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
161343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case MAP_TYPE:
1614ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org      Map::BodyDescriptor::IterateBody(this, v);
161543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
161643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case CODE_TYPE:
161743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      reinterpret_cast<Code*>(this)->CodeIterateBody(v);
161843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
161941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    case CELL_TYPE:
162041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      Cell::BodyDescriptor::IterateBody(this, v);
162141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      break;
162241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    case PROPERTY_CELL_TYPE:
1623b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      PropertyCell::BodyDescriptor::IterateBody(this, v);
16242abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org      break;
16254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    case SYMBOL_TYPE:
1626f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      Symbol::BodyDescriptor::IterateBody(this, v);
1627f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      break;
1628af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
162943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case HEAP_NUMBER_TYPE:
163058a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org    case MUTABLE_HEAP_NUMBER_TYPE:
163143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case FILLER_TYPE:
163243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case BYTE_ARRAY_TYPE:
1633c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    case FREE_SPACE_TYPE:
163443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
1635af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
1636af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
1637af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_##TYPE##_ARRAY_TYPE:                                         \
1638af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case FIXED_##TYPE##_ARRAY_TYPE:                                            \
1639af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      break;
1640af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
1641af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(TYPED_ARRAY_CASE)
1642af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef TYPED_ARRAY_CASE
1643af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
16447d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    case SHARED_FUNCTION_INFO_TYPE: {
1645b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org      SharedFunctionInfo::BodyDescriptor::IterateBody(this, v);
164643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
16477d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org    }
1648ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
164943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define MAKE_STRUCT_CASE(NAME, Name, name) \
165043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        case NAME##_TYPE:
165143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      STRUCT_LIST(MAKE_STRUCT_CASE)
165243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef MAKE_STRUCT_CASE
1653ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      if (type == ALLOCATION_SITE_TYPE) {
1654ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        AllocationSite::BodyDescriptor::IterateBody(this, v);
1655ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      } else {
1656ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        StructBodyDescriptor::IterateBody(this, object_size, v);
1657ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      }
165843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
165943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    default:
166043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      PrintF("Unknown type: %d\n", type);
166143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      UNREACHABLE();
166243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
166343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
166443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
166543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
16669faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.orgbool HeapNumber::HeapNumberBooleanValue() {
166708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  return DoubleToBoolean(value());
166843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
166943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
167043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1671f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgvoid HeapNumber::HeapNumberPrint(OStream& os) {  // NOLINT
1672f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << value();
167343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
167443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
167543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1676d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.orgString* JSReceiver::class_name() {
16777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (IsJSFunction() || IsJSFunctionProxy()) {
16785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    return GetHeap()->Function_string();
1679a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  }
168043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (map()->constructor()->IsJSFunction()) {
168143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    JSFunction* constructor = JSFunction::cast(map()->constructor());
168243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return String::cast(constructor->shared()->instance_class_name());
168343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
16845a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // If the constructor is not present, return "Object".
16854a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return GetHeap()->Object_string();
168643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
168743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
168843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
168932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.orgString* Map::constructor_name() {
169032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  if (constructor()->IsJSFunction()) {
169132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    JSFunction* constructor = JSFunction::cast(this->constructor());
1692a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    String* name = String::cast(constructor->shared()->name());
169342841968c3c92e3b07bcd67e79eb6ba3f83032c1vegorov@chromium.org    if (name->length() > 0) return name;
169442841968c3c92e3b07bcd67e79eb6ba3f83032c1vegorov@chromium.org    String* inferred_name = constructor->shared()->inferred_name();
169542841968c3c92e3b07bcd67e79eb6ba3f83032c1vegorov@chromium.org    if (inferred_name->length() > 0) return inferred_name;
169632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    Object* proto = prototype();
169742841968c3c92e3b07bcd67e79eb6ba3f83032c1vegorov@chromium.org    if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name();
1698a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  }
1699d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  // TODO(rossberg): what about proxies?
1700a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // If the constructor is not present, return "Object".
17014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return GetHeap()->Object_string();
1702a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org}
1703a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
1704a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
170532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.orgString* JSReceiver::constructor_name() {
170632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  return map()->constructor_name();
170732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org}
170832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
170932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org
17109fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgMaybeHandle<Map> Map::CopyWithField(Handle<Map> map,
17119fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                    Handle<Name> name,
17129fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                    Handle<HeapType> type,
17139fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                    PropertyAttributes attributes,
17149fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                    Representation representation,
17159fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                    TransitionFlag flag) {
1716e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(DescriptorArray::kNotFound ==
17179fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org         map->instance_descriptors()->Search(
17189fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org             *name, map->NumberOfOwnDescriptors()));
17199fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
17209fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Ensure the descriptor array does not get too big.
17219fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) {
17229fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    return MaybeHandle<Map>();
17239fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
172483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
17259fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Isolate* isolate = map->GetIsolate();
1726c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
1727c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  // Compute the new index for new field.
17289fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int index = map->NextFreePropertyIndex();
17299fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
17309fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) {
17319fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    representation = Representation::Tagged();
17329fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    type = HeapType::Any(isolate);
17339fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
1734c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
1735e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  FieldDescriptor new_field_desc(name, index, type, attributes, representation);
17369fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag);
1737c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  int unused_property_fields = new_map->unused_property_fields() - 1;
1738c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  if (unused_property_fields < 0) {
1739c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    unused_property_fields += JSObject::kFieldsAdded;
1740c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  }
1741c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  new_map->set_unused_property_fields(unused_property_fields);
17429fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return new_map;
17439fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
17443c8b8b276e7d4a77a6082c4773879b7093440fb5mstarzinger@chromium.org
174597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
17469fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgMaybeHandle<Map> Map::CopyWithConstant(Handle<Map> map,
17479fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                       Handle<Name> name,
17489fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                       Handle<Object> constant,
17499fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                       PropertyAttributes attributes,
17509fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                       TransitionFlag flag) {
17519fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Ensure the descriptor array does not get too big.
17529fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) {
17539fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    return MaybeHandle<Map>();
175497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
17559fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
17569fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Allocate new instance descriptors with (name, constant) added.
17579fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  ConstantDescriptor new_constant_desc(name, constant, attributes);
17589fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return Map::CopyAddDescriptor(map, &new_constant_desc, flag);
1759528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org}
176043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
176143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1762528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid JSObject::AddSlowProperty(Handle<JSObject> object,
1763528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Handle<Name> name,
1764528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Handle<Object> value,
1765528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               PropertyAttributes attributes) {
1766e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->HasFastProperties());
1767528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Isolate* isolate = object->GetIsolate();
1768528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<NameDictionary> dict(object->property_dictionary());
1769528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (object->IsGlobalObject()) {
17702abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    // In case name is an orphaned property reuse the cell.
1771f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    int entry = dict->FindEntry(name);
1772750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (entry != NameDictionary::kNotFound) {
1773528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry)));
1774528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      PropertyCell::SetValueInferType(cell, value);
177586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      // Assign an enumeration index to the property and update
177686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      // SetNextEnumerationIndex.
177786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      int index = dict->NextEnumerationIndex();
177857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      PropertyDetails details = PropertyDetails(attributes, NORMAL, index);
177986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      dict->SetNextEnumerationIndex(index + 1);
1780865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      dict->SetEntry(entry, name, cell, details);
1781528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      return;
1782303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
1783528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(value);
1784528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    PropertyCell::SetValueInferType(cell, value);
1785528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    value = cell;
17862abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  }
178757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
1788c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  Handle<NameDictionary> result =
1789f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      NameDictionary::Add(dict, name, value, details);
1790528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (*dict != *result) object->set_properties(*result);
179143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
179243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
179343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1794c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.orgContext* JSObject::GetCreationContext() {
1795c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  Object* constructor = this->map()->constructor();
1796c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  JSFunction* function;
1797c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  if (!constructor->IsJSFunction()) {
1798c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    // Functions have null as a constructor,
1799c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    // but any JSFunction knows its context immediately.
1800c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    function = JSFunction::cast(this);
1801c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  } else {
1802c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    function = JSFunction::cast(constructor);
1803c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  }
1804c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
1805c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  return function->context()->native_context();
1806c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org}
1807c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
1808c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
1809e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid JSObject::EnqueueChangeRecord(Handle<JSObject> object,
1810e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                                   const char* type_str,
1811750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                   Handle<Name> name,
1812e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                                   Handle<Object> old_value) {
1813e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsJSGlobalProxy());
1814e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsJSGlobalObject());
1815e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Isolate* isolate = object->GetIsolate();
1816c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  HandleScope scope(isolate);
18174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str);
1818e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Handle<Object> args[] = { type, object, name, old_value };
1819057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  int argc = name.is_null() ? 2 : old_value->IsTheHole() ? 3 : 4;
1820057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
18212c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  Execution::Call(isolate,
18222c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org                  Handle<JSFunction>(isolate->observers_notify_change()),
182309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                  isolate->factory()->undefined_value(),
18242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                  argc, args).Assert();
1825e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
1826e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1827e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1828f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgconst char* Representation::Mnemonic() const {
1829f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  switch (kind_) {
1830f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    case kNone: return "v";
1831f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    case kTagged: return "t";
1832f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    case kSmi: return "s";
1833f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    case kDouble: return "d";
1834f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    case kInteger32: return "i";
1835906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    case kHeapObject: return "h";
1836f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    case kExternal: return "x";
1837f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    default:
1838f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      UNREACHABLE();
1839f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      return NULL;
1840f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
1841f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
1842f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
1843f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
1844f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.orgbool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields,
1845f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org                                 int target_inobject, int target_unused,
1846f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org                                 int* old_number_of_fields) {
1847f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // If fields were added (or removed), rewrite the instance.
1848f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org  *old_number_of_fields = NumberOfFields();
1849e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(target_number_of_fields >= *old_number_of_fields);
1850f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org  if (target_number_of_fields != *old_number_of_fields) return true;
185157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
1852bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  // If smi descriptors were replaced by double descriptors, rewrite.
1853bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  DescriptorArray* old_desc = instance_descriptors();
1854bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  DescriptorArray* new_desc = target->instance_descriptors();
1855bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  int limit = NumberOfOwnDescriptors();
1856bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  for (int i = 0; i < limit; i++) {
185758a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org    if (new_desc->GetDetails(i).representation().IsDouble() !=
185858a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org        old_desc->GetDetails(i).representation().IsDouble()) {
1859bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      return true;
186057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    }
186157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
186257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
1863f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // If no fields were added, and no inobject properties were removed, setting
1864f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // the map is sufficient.
1865f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (target_inobject == inobject_properties()) return false;
1866f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // In-object slack tracking may have reduced the object size of the new map.
1867f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // In that case, succeed if all existing fields were inobject, and they still
1868f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // fit within the new inobject size.
1869e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(target_inobject < inobject_properties());
1870f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (target_number_of_fields <= target_inobject) {
1871e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(target_number_of_fields + target_unused == target_inobject);
1872f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    return false;
1873f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
1874f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // Otherwise, properties will need to be moved to the backing store.
1875f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  return true;
1876f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
1877f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
1878f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
1879e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid Map::ConnectElementsTransition(Handle<Map> parent, Handle<Map> child) {
1880e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Isolate* isolate = parent->GetIsolate();
1881e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Handle<Name> name = isolate->factory()->elements_transition_symbol();
1882e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  ConnectTransition(parent, child, name, FULL_TRANSITION);
18835b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org}
18845b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org
18855b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org
188608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgvoid JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
188708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  if (object->map() == *new_map) return;
188808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  if (object->HasFastProperties()) {
188908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    if (!new_map->is_dictionary_map()) {
1890e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      Handle<Map> old_map(object->map());
189108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      MigrateFastToFast(object, new_map);
1892e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      if (old_map->is_prototype_map()) {
1893e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        // Clear out the old descriptor array to avoid problems to sharing
1894e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        // the descriptor array without using an explicit.
1895e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        old_map->InitializeDescriptors(
1896e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org            old_map->GetHeap()->empty_descriptor_array());
1897e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        // Ensure that no transition was inserted for prototype migrations.
1898e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(!old_map->HasTransitionArray());
1899e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(new_map->GetBackPointer()->IsUndefined());
1900e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      }
190108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    } else {
190208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      MigrateFastToSlow(object, new_map, 0);
190308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    }
190408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  } else {
190508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    // For slow-to-fast migrations JSObject::TransformToFastProperties()
190608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    // must be used instead.
190708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    CHECK(new_map->is_dictionary_map());
190808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org
190908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    // Slow-to-slow migration is trivial.
191008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    object->set_map(*new_map);
191108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  }
191208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org}
191308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org
191408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org
191508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org// To migrate a fast instance to a fast map:
1916f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org// - First check whether the instance needs to be rewritten. If not, simply
1917f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org//   change the map.
1918f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org// - Otherwise, allocate a fixed array large enough to hold all fields, in
1919f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org//   addition to unused space.
1920f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org// - Copy all existing properties in, in the following order: backing store
1921f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org//   properties, unused fields, inobject properties.
1922f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org// - If all allocation succeeded, commit the state atomically:
1923f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org//   * Copy inobject properties from the backing store back into the object.
1924f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org//   * Trim the difference in instance size of the object. This also cleanly
1925f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org//     frees inobject properties that moved to the backing store.
1926f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org//   * If there are properties left in the backing store, trim of the space used
1927f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org//     to temporarily store the inobject properties.
1928f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org//   * If there are properties left in the backing store, install the backing
1929f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org//     store.
193008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgvoid JSObject::MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
19313d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  Isolate* isolate = object->GetIsolate();
19323d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  Handle<Map> old_map(object->map());
1933f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org  int old_number_of_fields;
1934f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  int number_of_fields = new_map->NumberOfFields();
1935f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  int inobject = new_map->inobject_properties();
1936f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  int unused = new_map->unused_property_fields();
1937f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
19383d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // Nothing to do if no functions were converted to fields and no smis were
19393d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // converted to doubles.
1940f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org  if (!old_map->InstancesNeedRewriting(*new_map, number_of_fields, inobject,
1941f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org                                       unused, &old_number_of_fields)) {
194263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org    object->synchronized_set_map(*new_map);
19433d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    return;
1944f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
1945f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
1946f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  int total_size = number_of_fields + unused;
1947f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  int external = total_size - inobject;
1948975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
1949a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  if (number_of_fields != old_number_of_fields &&
1950a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      new_map->GetBackPointer() == *old_map) {
1951a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    PropertyDetails details = new_map->GetLastDescriptorDetails();
1952a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
1953a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    if (old_map->unused_property_fields() > 0) {
1954a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      if (details.representation().IsDouble()) {
1955a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org        Handle<Object> value = isolate->factory()->NewHeapNumber(0, MUTABLE);
1956a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org        FieldIndex index =
1957a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org            FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
1958a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org        object->FastPropertyAtPut(index, *value);
1959a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      }
1960a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      object->synchronized_set_map(*new_map);
1961a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      return;
1962a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    }
1963a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
1964e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(number_of_fields == old_number_of_fields + 1);
1965975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    // This migration is a transition from a map that has run out out property
1966975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    // space. Therefore it could be done by extending the backing store.
1967975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    Handle<FixedArray> old_storage = handle(object->properties(), isolate);
1968975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    Handle<FixedArray> new_storage =
1969975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org        FixedArray::CopySize(old_storage, external);
1970975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
1971975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    // Properly initialize newly added property.
1972975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    Handle<Object> value;
1973975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    if (details.representation().IsDouble()) {
197458a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org      value = isolate->factory()->NewHeapNumber(0, MUTABLE);
1975975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    } else {
1976975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org      value = isolate->factory()->uninitialized_value();
1977975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    }
1978e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(details.type() == FIELD);
1979975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    int target_index = details.field_index() - inobject;
1980e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(target_index >= 0);  // Must be a backing store index.
1981975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    new_storage->set(target_index, *value);
1982975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
1983975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    // From here on we cannot fail and we shouldn't GC anymore.
1984975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    DisallowHeapAllocation no_allocation;
1985975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
1986975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    // Set the new property value and do the map transition.
1987975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    object->set_properties(*new_storage);
198808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    object->synchronized_set_map(*new_map);
1989975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    return;
1990975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  }
19913d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size);
1992f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
19933d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
19943d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors());
199597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  int old_nof = old_map->NumberOfOwnDescriptors();
199697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  int new_nof = new_map->NumberOfOwnDescriptors();
199797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
199897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // This method only supports generalizing instances to at least the same
199997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // number of properties.
2000e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(old_nof <= new_nof);
2001f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
200297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  for (int i = 0; i < old_nof; i++) {
2003f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    PropertyDetails details = new_descriptors->GetDetails(i);
2004f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (details.type() != FIELD) continue;
2005f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    PropertyDetails old_details = old_descriptors->GetDetails(i);
20061e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    if (old_details.type() == CALLBACKS) {
2007e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(details.representation().IsTagged());
20081e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      continue;
20091e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    }
2010e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(old_details.type() == CONSTANT ||
2011f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org           old_details.type() == FIELD);
20123d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    Object* raw_value = old_details.type() == CONSTANT
2013f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org        ? old_descriptors->GetValue(i)
2014e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        : object->RawFastPropertyAt(FieldIndex::ForDescriptor(*old_map, i));
20153d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    Handle<Object> value(raw_value, isolate);
2016bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    if (!old_details.representation().IsDouble() &&
201757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        details.representation().IsDouble()) {
20183d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org      if (old_details.representation().IsNone()) {
20193d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org        value = handle(Smi::FromInt(0), isolate);
20203d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org      }
2021e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      value = Object::NewStorageFor(isolate, value, details.representation());
202258a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org    } else if (old_details.representation().IsDouble() &&
202358a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org               !details.representation().IsDouble()) {
202458a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org      value = Object::WrapForRead(isolate, value, old_details.representation());
202557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    }
2026e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!(details.representation().IsDouble() && value->IsSmi()));
2027f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    int target_index = new_descriptors->GetFieldIndex(i) - inobject;
2028f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (target_index < 0) target_index += total_size;
20293d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    array->set(target_index, *value);
2030f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
2031f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
203297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  for (int i = old_nof; i < new_nof; i++) {
203397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    PropertyDetails details = new_descriptors->GetDetails(i);
203497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    if (details.type() != FIELD) continue;
2035e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<Object> value;
203697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    if (details.representation().IsDouble()) {
203758a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org      value = isolate->factory()->NewHeapNumber(0, MUTABLE);
2038e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    } else {
2039e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      value = isolate->factory()->uninitialized_value();
204097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    }
2041e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    int target_index = new_descriptors->GetFieldIndex(i) - inobject;
2042e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    if (target_index < 0) target_index += total_size;
2043e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    array->set(target_index, *value);
204497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
204597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
20463d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // From here on we cannot fail and we shouldn't GC anymore.
20473d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  DisallowHeapAllocation no_allocation;
2048f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2049f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // Copy (real) inobject properties. If necessary, stop at number_of_fields to
2050f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // avoid overwriting |one_pointer_filler_map|.
2051f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  int limit = Min(inobject, number_of_fields);
2052f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  for (int i = 0; i < limit; i++) {
2053e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
2054e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    object->FastPropertyAtPut(index, array->get(external + i));
2055f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
2056f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
205708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Heap* heap = isolate->heap();
2058f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2059f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // If there are properties in the new backing store, trim it to the correct
2060f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // size and install the backing store into the object.
2061f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (external > 0) {
20623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    heap->RightTrimFixedArray<Heap::FROM_MUTATOR>(*array, inobject);
20633d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    object->set_properties(*array);
2064f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
2065f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
206647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  // Create filler object past the new instance size.
206747390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  int new_instance_size = new_map->instance_size();
206847390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  int instance_size_delta = old_map->instance_size() - new_instance_size;
2069e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(instance_size_delta >= 0);
207047390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org
207147390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  if (instance_size_delta > 0) {
207247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org    Address address = object->address();
207347390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org    heap->CreateFillerObjectAt(
207447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org        address + new_instance_size, instance_size_delta);
207547390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org    heap->AdjustLiveBytes(address, -instance_size_delta, Heap::FROM_MUTATOR);
207647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  }
207708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org
207808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  // We are storing the new map using release store after creating a filler for
207908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  // the left-over space to avoid races with the sweeper thread.
208008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  object->synchronized_set_map(*new_map);
2081f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
2082f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2083f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2084528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
2085528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                             int modify_index,
2086528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                             Representation new_representation,
20879d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                                             Handle<HeapType> new_field_type) {
2088528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<Map> new_map = Map::GeneralizeRepresentation(
20899d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org      handle(object->map()), modify_index, new_representation, new_field_type,
20909d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org      FORCE_FIELD);
209108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  MigrateToMap(object, new_map);
2092f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
2093f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2094f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2095f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgint Map::NumberOfFields() {
2096f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  DescriptorArray* descriptors = instance_descriptors();
2097f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  int result = 0;
2098f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  for (int i = 0; i < NumberOfOwnDescriptors(); i++) {
2099f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (descriptors->GetDetails(i).type() == FIELD) result++;
2100f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
2101f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  return result;
2102f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
2103f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2104f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2105528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgHandle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
2106528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                                  int modify_index,
2107528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                                  StoreMode store_mode,
2108528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                                  PropertyAttributes attributes,
2109528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                                  const char* reason) {
2110e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Isolate* isolate = map->GetIsolate();
2111528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<Map> new_map = Copy(map);
2112f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
21139259716434187c932704601f700375e53d865de8rossberg@chromium.org  DescriptorArray* descriptors = new_map->instance_descriptors();
2114e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  int length = descriptors->number_of_descriptors();
2115e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  for (int i = 0; i < length; i++) {
2116e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    descriptors->SetRepresentation(i, Representation::Tagged());
2117e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    if (descriptors->GetDetails(i).type() == FIELD) {
2118e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      descriptors->SetValue(i, HeapType::Any());
2119e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    }
2120e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  }
21219259716434187c932704601f700375e53d865de8rossberg@chromium.org
21229259716434187c932704601f700375e53d865de8rossberg@chromium.org  // Unless the instance is being migrated, ensure that modify_index is a field.
21239259716434187c932704601f700375e53d865de8rossberg@chromium.org  PropertyDetails details = descriptors->GetDetails(modify_index);
212470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  if (store_mode == FORCE_FIELD &&
212570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      (details.type() != FIELD || details.attributes() != attributes)) {
212670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    int field_index = details.type() == FIELD ? details.field_index()
212770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org                                              : new_map->NumberOfFields();
2128e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate),
212970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org                      field_index, attributes, Representation::Tagged());
2130202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    descriptors->Replace(modify_index, &d);
213170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    if (details.type() != FIELD) {
213270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      int unused_property_fields = new_map->unused_property_fields() - 1;
213370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      if (unused_property_fields < 0) {
213470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org        unused_property_fields += JSObject::kFieldsAdded;
213570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      }
213670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      new_map->set_unused_property_fields(unused_property_fields);
21379259716434187c932704601f700375e53d865de8rossberg@chromium.org    }
213870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  } else {
2139e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(details.attributes() == attributes);
21409259716434187c932704601f700375e53d865de8rossberg@chromium.org  }
21419259716434187c932704601f700375e53d865de8rossberg@chromium.org
214257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  if (FLAG_trace_generalization) {
2143e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    HeapType* field_type = (details.type() == FIELD)
2144e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        ? map->instance_descriptors()->GetFieldType(modify_index)
2145e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        : NULL;
2146528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    map->PrintGeneralization(stdout, reason, modify_index,
21479259716434187c932704601f700375e53d865de8rossberg@chromium.org                        new_map->NumberOfOwnDescriptors(),
21489259716434187c932704601f700375e53d865de8rossberg@chromium.org                        new_map->NumberOfOwnDescriptors(),
21499259716434187c932704601f700375e53d865de8rossberg@chromium.org                        details.type() == CONSTANT && store_mode == FORCE_FIELD,
2150e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                        details.representation(), Representation::Tagged(),
2151e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                        field_type, HeapType::Any());
215257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
2153f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  return new_map;
2154f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
2155f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2156f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2157e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org// static
2158e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.orgHandle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
2159e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                                  int modify_index,
2160e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                                  StoreMode store_mode,
2161e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                                  const char* reason) {
2162e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  PropertyDetails details =
2163e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      map->instance_descriptors()->GetDetails(modify_index);
2164e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  return CopyGeneralizeAllRepresentations(map, modify_index, store_mode,
2165e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                          details.attributes(), reason);
2166e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org}
2167e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org
2168e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org
2169f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgvoid Map::DeprecateTransitionTree() {
2170f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (is_deprecated()) return;
2171f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (HasTransitionArray()) {
2172f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    TransitionArray* transitions = this->transitions();
2173f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    for (int i = 0; i < transitions->number_of_transitions(); i++) {
2174f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      transitions->GetTarget(i)->DeprecateTransitionTree();
2175f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    }
2176f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
2177f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  deprecate();
2178f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  dependent_code()->DeoptimizeDependentCodeGroup(
2179f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      GetIsolate(), DependentCode::kTransitionGroup);
2180d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  NotifyLeafMapLayoutChange();
2181f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
2182f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2183f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2184f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org// Invalidates a transition target at |key|, and installs |new_descriptors| over
2185f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org// the current instance_descriptors to ensure proper sharing of descriptor
2186f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org// arrays.
2187f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgvoid Map::DeprecateTarget(Name* key, DescriptorArray* new_descriptors) {
2188f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (HasTransitionArray()) {
2189f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    TransitionArray* transitions = this->transitions();
2190f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    int transition = transitions->Search(key);
2191f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (transition != TransitionArray::kNotFound) {
2192f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      transitions->GetTarget(transition)->DeprecateTransitionTree();
2193f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    }
2194f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
2195f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2196f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // Don't overwrite the empty descriptor array.
2197f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (NumberOfOwnDescriptors() == 0) return;
2198f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2199f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  DescriptorArray* to_replace = instance_descriptors();
2200f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  Map* current = this;
2201f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  GetHeap()->incremental_marking()->RecordWrites(to_replace);
2202f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  while (current->instance_descriptors() == to_replace) {
2203af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    current->SetEnumLength(kInvalidEnumCacheSentinel);
2204f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    current->set_instance_descriptors(new_descriptors);
2205f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    Object* next = current->GetBackPointer();
2206f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (next->IsUndefined()) break;
2207f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    current = Map::cast(next);
2208f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
2209f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2210f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  set_owns_descriptors(false);
2211f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
2212f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2213f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2214f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgMap* Map::FindRootMap() {
2215f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  Map* result = this;
2216f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  while (true) {
2217f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    Object* back = result->GetBackPointer();
2218f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (back->IsUndefined()) return result;
2219f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    result = Map::cast(back);
2220f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
2221f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
2222f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2223f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2224f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgMap* Map::FindLastMatchMap(int verbatim,
2225f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                           int length,
2226f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                           DescriptorArray* descriptors) {
2227e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  DisallowHeapAllocation no_allocation;
2228e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
2229f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // This can only be called on roots of transition trees.
2230e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(GetBackPointer()->IsUndefined());
2231f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2232f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  Map* current = this;
2233f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2234f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  for (int i = verbatim; i < length; i++) {
2235f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (!current->HasTransitionArray()) break;
2236f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    Name* name = descriptors->GetKey(i);
2237f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    TransitionArray* transitions = current->transitions();
2238f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    int transition = transitions->Search(name);
2239f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (transition == TransitionArray::kNotFound) break;
2240f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2241f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    Map* next = transitions->GetTarget(transition);
2242f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    DescriptorArray* next_descriptors = next->instance_descriptors();
2243f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2244f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    PropertyDetails details = descriptors->GetDetails(i);
2245f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    PropertyDetails next_details = next_descriptors->GetDetails(i);
2246f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (details.type() != next_details.type()) break;
2247f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (details.attributes() != next_details.attributes()) break;
2248f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (!details.representation().Equals(next_details.representation())) break;
2249e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    if (next_details.type() == FIELD) {
2250e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      if (!descriptors->GetFieldType(i)->NowIs(
2251e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org              next_descriptors->GetFieldType(i))) break;
2252e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    } else {
2253e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break;
2254e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    }
2255f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2256f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    current = next;
2257f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
2258f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  return current;
2259f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
2260f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2261f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2262e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgMap* Map::FindFieldOwner(int descriptor) {
2263e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  DisallowHeapAllocation no_allocation;
2264e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(FIELD, instance_descriptors()->GetDetails(descriptor).type());
2265e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Map* result = this;
2266e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  while (true) {
2267e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Object* back = result->GetBackPointer();
2268e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    if (back->IsUndefined()) break;
2269e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Map* parent = Map::cast(back);
2270e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    if (parent->NumberOfOwnDescriptors() <= descriptor) break;
2271e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    result = parent;
2272e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  }
2273e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return result;
2274e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org}
2275e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
2276e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
2277dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid Map::UpdateFieldType(int descriptor, Handle<Name> name,
2278dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org                          Handle<HeapType> new_type) {
2279e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  DisallowHeapAllocation no_allocation;
2280dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  PropertyDetails details = instance_descriptors()->GetDetails(descriptor);
2281dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  if (details.type() != FIELD) return;
2282e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (HasTransitionArray()) {
2283e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    TransitionArray* transitions = this->transitions();
2284e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    for (int i = 0; i < transitions->number_of_transitions(); ++i) {
2285dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      transitions->GetTarget(i)->UpdateFieldType(descriptor, name, new_type);
2286e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    }
2287e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  }
2288dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  // Skip if already updated the shared descriptor.
2289dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  if (instance_descriptors()->GetFieldType(descriptor) == *new_type) return;
2290dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  FieldDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor),
2291dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org                    new_type, details.attributes(), details.representation());
2292dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  instance_descriptors()->Replace(descriptor, &d);
2293e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org}
2294e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
2295e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
2296e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org// static
22978496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.orgHandle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1,
22988496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                          Handle<HeapType> type2,
2299e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                          Isolate* isolate) {
23008496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  static const int kMaxClassesPerFieldType = 5;
23018496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (type1->NowIs(type2)) return type2;
23028496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (type2->NowIs(type1)) return type1;
23038496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (type1->NowStable() && type2->NowStable()) {
23048496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    Handle<HeapType> type = HeapType::Union(type1, type2, isolate);
23058496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    if (type->NumClasses() <= kMaxClassesPerFieldType) {
2306e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(type->NowStable());
2307e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(type1->NowIs(type));
2308e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(type2->NowIs(type));
23098496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      return type;
23108496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    }
23118496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  }
2312e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return HeapType::Any(isolate);
2313e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org}
2314e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
2315e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
2316e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org// static
2317e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgvoid Map::GeneralizeFieldType(Handle<Map> map,
2318e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                              int modify_index,
2319e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                              Handle<HeapType> new_field_type) {
2320e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Isolate* isolate = map->GetIsolate();
2321e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
2322e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  // Check if we actually need to generalize the field type at all.
2323e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Handle<HeapType> old_field_type(
2324a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      map->instance_descriptors()->GetFieldType(modify_index), isolate);
2325e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (new_field_type->NowIs(old_field_type)) {
2326e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(Map::GeneralizeFieldType(old_field_type,
2327e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                    new_field_type,
2328e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                    isolate)->NowIs(old_field_type));
2329e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    return;
2330e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  }
2331e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
2332a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  // Determine the field owner.
2333a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate);
2334a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Handle<DescriptorArray> descriptors(
2335a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      field_owner->instance_descriptors(), isolate);
2336e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index));
2337a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org
2338e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  // Determine the generalized new field type.
2339e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  new_field_type = Map::GeneralizeFieldType(
2340e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      old_field_type, new_field_type, isolate);
2341e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
2342e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  PropertyDetails details = descriptors->GetDetails(modify_index);
2343dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  Handle<Name> name(descriptors->GetKey(modify_index));
2344dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  field_owner->UpdateFieldType(modify_index, name, new_field_type);
2345e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
2346e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      isolate, DependentCode::kFieldTypeGroup);
2347e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
2348e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (FLAG_trace_generalization) {
2349e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    map->PrintGeneralization(
2350e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        stdout, "field type generalization",
2351e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        modify_index, map->NumberOfOwnDescriptors(),
2352e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        map->NumberOfOwnDescriptors(), false,
2353e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        details.representation(), details.representation(),
2354e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        *old_field_type, *new_field_type);
2355e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  }
2356e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org}
2357e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
2358e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
2359f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org// Generalize the representation of the descriptor at |modify_index|.
2360f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org// This method rewrites the transition tree to reflect the new change. To avoid
2361f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org// high degrees over polymorphism, and to stabilize quickly, on every rewrite
2362f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org// the new type is deduced by merging the current type with any potential new
2363f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org// (partial) version of the type in the transition tree.
2364f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org// To do this, on each rewrite:
2365f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org// - Search the root of the transition tree using FindRootMap.
2366a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org// - Find |target_map|, the newest matching version of this map using the keys
2367a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org//   in the |old_map|'s descriptor array to walk the transition tree.
2368a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org// - Merge/generalize the descriptor array of the |old_map| and |target_map|.
2369a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org// - Generalize the |modify_index| descriptor using |new_representation| and
2370a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org//   |new_field_type|.
2371a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org// - Walk the tree again starting from the root towards |target_map|. Stop at
2372f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org//   |split_map|, the first map who's descriptor array does not match the merged
2373f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org//   descriptor array.
2374a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org// - If |target_map| == |split_map|, |target_map| is in the expected state.
2375a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org//   Return it.
2376a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org// - Otherwise, invalidate the outdated transition target from |target_map|, and
2377f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org//   replace its transition tree with a new branch for the updated descriptors.
2378528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgHandle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
2379528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                          int modify_index,
2380528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                          Representation new_representation,
2381e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                          Handle<HeapType> new_field_type,
2382528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                          StoreMode store_mode) {
2383a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Isolate* isolate = old_map->GetIsolate();
2384a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org
2385a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Handle<DescriptorArray> old_descriptors(
2386a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      old_map->instance_descriptors(), isolate);
2387a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  int old_nof = old_map->NumberOfOwnDescriptors();
23881e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
23891e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  Representation old_representation = old_details.representation();
2390f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
23911fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  // It's fine to transition from None to anything but double without any
23921fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  // modification to the object, because the default uninitialized value for
23931fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  // representation None can be overwritten by both smi and tagged values.
23941fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  // Doubles, however, would require a box allocation.
23951fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  if (old_representation.IsNone() &&
23961fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      !new_representation.IsNone() &&
23971fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      !new_representation.IsDouble()) {
2398e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(old_details.type() == FIELD);
2399e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(old_descriptors->GetFieldType(modify_index)->NowIs(
2400e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org            HeapType::None()));
2401e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    if (FLAG_trace_generalization) {
2402e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      old_map->PrintGeneralization(
2403e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org          stdout, "uninitialized field",
2404e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org          modify_index, old_map->NumberOfOwnDescriptors(),
2405e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org          old_map->NumberOfOwnDescriptors(), false,
2406e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org          old_representation, new_representation,
2407e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org          old_descriptors->GetFieldType(modify_index), *new_field_type);
2408e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    }
2409f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    old_descriptors->SetRepresentation(modify_index, new_representation);
2410e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    old_descriptors->SetValue(modify_index, *new_field_type);
2411e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    return old_map;
2412e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  }
2413e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
2414bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  // Check the state of the root map.
2415a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Handle<Map> root_map(old_map->FindRootMap(), isolate);
2416528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (!old_map->EquivalentToForTransition(*root_map)) {
2417e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    return CopyGeneralizeAllRepresentations(
2418e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        old_map, modify_index, store_mode, "not equivalent");
2419f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
2420a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  int root_nof = root_map->NumberOfOwnDescriptors();
2421a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  if (modify_index < root_nof) {
2422a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2423a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if ((old_details.type() != FIELD && store_mode == FORCE_FIELD) ||
2424a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        (old_details.type() == FIELD &&
2425a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org         (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) ||
2426a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          !new_representation.fits_into(old_details.representation())))) {
2427e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      return CopyGeneralizeAllRepresentations(
2428e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org          old_map, modify_index, store_mode, "root modification");
2429a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    }
2430a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  }
2431f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2432a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Handle<Map> target_map = root_map;
2433a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  for (int i = root_nof; i < old_nof; ++i) {
2434a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    int j = target_map->SearchTransition(old_descriptors->GetKey(i));
2435a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if (j == TransitionArray::kNotFound) break;
2436a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
2437a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    Handle<DescriptorArray> tmp_descriptors = handle(
2438a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        tmp_map->instance_descriptors(), isolate);
2439f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2440a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    // Check if target map is incompatible.
2441a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyDetails old_details = old_descriptors->GetDetails(i);
2442a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
2443a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyType old_type = old_details.type();
2444a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyType tmp_type = tmp_details.type();
2445a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if (tmp_details.attributes() != old_details.attributes() ||
2446a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        ((tmp_type == CALLBACKS || old_type == CALLBACKS) &&
2447a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org         (tmp_type != old_type ||
2448a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) {
2449a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      return CopyGeneralizeAllRepresentations(
2450e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org          old_map, modify_index, store_mode, "incompatible");
2451a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    }
2452a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    Representation old_representation = old_details.representation();
2453a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    Representation tmp_representation = tmp_details.representation();
2454a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if (!old_representation.fits_into(tmp_representation) ||
2455a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        (!new_representation.fits_into(tmp_representation) &&
2456a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org         modify_index == i)) {
2457a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      break;
2458a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    }
2459a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if (tmp_type == FIELD) {
2460a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      // Generalize the field type as necessary.
2461a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      Handle<HeapType> old_field_type = (old_type == FIELD)
2462a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          ? handle(old_descriptors->GetFieldType(i), isolate)
2463a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          : old_descriptors->GetValue(i)->OptimalType(
2464a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org              isolate, tmp_representation);
2465a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      if (modify_index == i) {
2466a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        old_field_type = GeneralizeFieldType(
2467a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org            new_field_type, old_field_type, isolate);
2468a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      }
2469a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      GeneralizeFieldType(tmp_map, i, old_field_type);
2470a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    } else if (tmp_type == CONSTANT) {
2471a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      if (old_type != CONSTANT ||
2472a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          old_descriptors->GetConstant(i) != tmp_descriptors->GetConstant(i)) {
2473a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        break;
2474a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      }
2475a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    } else {
2476e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK_EQ(tmp_type, old_type);
2477e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK_EQ(tmp_descriptors->GetValue(i), old_descriptors->GetValue(i));
2478a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    }
2479a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    target_map = tmp_map;
2480a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  }
2481a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org
2482a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  // Directly change the map if the target map is more general.
2483a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Handle<DescriptorArray> target_descriptors(
2484a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      target_map->instance_descriptors(), isolate);
2485a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  int target_nof = target_map->NumberOfOwnDescriptors();
2486a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  if (target_nof == old_nof &&
2487a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      (store_mode != FORCE_FIELD ||
2488a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org       target_descriptors->GetDetails(modify_index).type() == FIELD)) {
2489e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(modify_index < target_nof);
2490e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(new_representation.fits_into(
2491a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org            target_descriptors->GetDetails(modify_index).representation()));
2492e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(target_descriptors->GetDetails(modify_index).type() != FIELD ||
2493a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org           new_field_type->NowIs(
2494a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org               target_descriptors->GetFieldType(modify_index)));
2495a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    return target_map;
2496a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  }
2497a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org
2498a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  // Find the last compatible target map in the transition tree.
2499a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  for (int i = target_nof; i < old_nof; ++i) {
2500a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    int j = target_map->SearchTransition(old_descriptors->GetKey(i));
2501a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if (j == TransitionArray::kNotFound) break;
2502a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
2503a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    Handle<DescriptorArray> tmp_descriptors(
2504a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        tmp_map->instance_descriptors(), isolate);
2505a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org
2506a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    // Check if target map is compatible.
2507a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyDetails old_details = old_descriptors->GetDetails(i);
2508a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
2509a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if (tmp_details.attributes() != old_details.attributes() ||
2510a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) &&
2511a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org         (tmp_details.type() != old_details.type() ||
2512a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) {
2513a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      return CopyGeneralizeAllRepresentations(
2514e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org          old_map, modify_index, store_mode, "incompatible");
2515a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    }
2516a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    target_map = tmp_map;
25179259716434187c932704601f700375e53d865de8rossberg@chromium.org  }
2518a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  target_nof = target_map->NumberOfOwnDescriptors();
2519a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  target_descriptors = handle(target_map->instance_descriptors(), isolate);
25209259716434187c932704601f700375e53d865de8rossberg@chromium.org
2521a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  // Allocate a new descriptor array large enough to hold the required
2522a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  // descriptors, with minimally the exact same size as the old descriptor
2523a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  // array.
2524a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  int new_slack = Max(
2525a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      old_nof, old_descriptors->number_of_descriptors()) - old_nof;
2526a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Handle<DescriptorArray> new_descriptors = DescriptorArray::Allocate(
2527a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      isolate, old_nof, new_slack);
2528e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(new_descriptors->length() > target_descriptors->length() ||
2529a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org         new_descriptors->NumberOfSlackDescriptors() > 0 ||
2530a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org         new_descriptors->number_of_descriptors() ==
2531a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org         old_descriptors->number_of_descriptors());
2532e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(new_descriptors->number_of_descriptors() == old_nof);
2533a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org
2534a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  // 0 -> |root_nof|
2535a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  int current_offset = 0;
2536a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  for (int i = 0; i < root_nof; ++i) {
2537a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyDetails old_details = old_descriptors->GetDetails(i);
2538a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if (old_details.type() == FIELD) current_offset++;
2539a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    Descriptor d(handle(old_descriptors->GetKey(i), isolate),
2540a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                 handle(old_descriptors->GetValue(i), isolate),
2541a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                 old_details);
2542a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    new_descriptors->Set(i, &d);
25439259716434187c932704601f700375e53d865de8rossberg@chromium.org  }
25444e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
2545a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  // |root_nof| -> |target_nof|
2546a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  for (int i = root_nof; i < target_nof; ++i) {
2547a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    Handle<Name> target_key(target_descriptors->GetKey(i), isolate);
2548a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyDetails old_details = old_descriptors->GetDetails(i);
2549a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyDetails target_details = target_descriptors->GetDetails(i);
2550a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    target_details = target_details.CopyWithRepresentation(
2551a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        old_details.representation().generalize(
2552a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org            target_details.representation()));
2553a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if (modify_index == i) {
2554a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      target_details = target_details.CopyWithRepresentation(
2555a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          new_representation.generalize(target_details.representation()));
2556a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    }
2557e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK_EQ(old_details.attributes(), target_details.attributes());
2558a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if (old_details.type() == FIELD ||
2559a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        target_details.type() == FIELD ||
2560a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        (modify_index == i && store_mode == FORCE_FIELD) ||
2561a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        (target_descriptors->GetValue(i) != old_descriptors->GetValue(i))) {
2562a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      Handle<HeapType> old_field_type = (old_details.type() == FIELD)
2563a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          ? handle(old_descriptors->GetFieldType(i), isolate)
2564a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          : old_descriptors->GetValue(i)->OptimalType(
2565a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org              isolate, target_details.representation());
2566a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      Handle<HeapType> target_field_type = (target_details.type() == FIELD)
2567a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          ? handle(target_descriptors->GetFieldType(i), isolate)
2568a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          : target_descriptors->GetValue(i)->OptimalType(
2569a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org              isolate, target_details.representation());
2570a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      target_field_type = GeneralizeFieldType(
2571a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          target_field_type, old_field_type, isolate);
2572a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      if (modify_index == i) {
2573a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        target_field_type = GeneralizeFieldType(
2574a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org            target_field_type, new_field_type, isolate);
2575a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      }
2576a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      FieldDescriptor d(target_key,
2577a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                        current_offset++,
2578a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                        target_field_type,
2579a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                        target_details.attributes(),
2580a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                        target_details.representation());
2581a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      new_descriptors->Set(i, &d);
2582a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    } else {
2583e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK_NE(FIELD, target_details.type());
2584a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      Descriptor d(target_key,
2585a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                   handle(target_descriptors->GetValue(i), isolate),
2586a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                   target_details);
2587a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      new_descriptors->Set(i, &d);
2588a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    }
2589a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  }
25909259716434187c932704601f700375e53d865de8rossberg@chromium.org
2591a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  // |target_nof| -> |old_nof|
2592a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  for (int i = target_nof; i < old_nof; ++i) {
2593a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyDetails old_details = old_descriptors->GetDetails(i);
2594a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    Handle<Name> old_key(old_descriptors->GetKey(i), isolate);
2595a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if (modify_index == i) {
2596a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      old_details = old_details.CopyWithRepresentation(
2597a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          new_representation.generalize(old_details.representation()));
2598a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    }
2599a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if (old_details.type() == FIELD) {
2600a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      Handle<HeapType> old_field_type(
2601a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          old_descriptors->GetFieldType(i), isolate);
2602a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      if (modify_index == i) {
2603a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        old_field_type = GeneralizeFieldType(
2604a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org            old_field_type, new_field_type, isolate);
2605a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      }
2606a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      FieldDescriptor d(old_key,
2607a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                        current_offset++,
2608a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                        old_field_type,
2609a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                        old_details.attributes(),
2610a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                        old_details.representation());
2611a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      new_descriptors->Set(i, &d);
2612a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    } else {
2613e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(old_details.type() == CONSTANT || old_details.type() == CALLBACKS);
2614a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      if (modify_index == i && store_mode == FORCE_FIELD) {
2615a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        FieldDescriptor d(old_key,
2616a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                          current_offset++,
2617a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                          GeneralizeFieldType(
2618a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                              old_descriptors->GetValue(i)->OptimalType(
2619a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                                  isolate, old_details.representation()),
2620a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                              new_field_type, isolate),
2621a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                          old_details.attributes(),
2622a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                          old_details.representation());
2623a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        new_descriptors->Set(i, &d);
2624a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      } else {
2625e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK_NE(FIELD, old_details.type());
2626a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        Descriptor d(old_key,
2627a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                     handle(old_descriptors->GetValue(i), isolate),
2628a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                     old_details);
2629a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        new_descriptors->Set(i, &d);
2630a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      }
2631a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    }
263257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
263357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
2634a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  new_descriptors->Sort();
2635f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2636e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(store_mode != FORCE_FIELD ||
2637a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org         new_descriptors->GetDetails(modify_index).type() == FIELD);
2638f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2639528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<Map> split_map(root_map->FindLastMatchMap(
2640a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          root_nof, old_nof, *new_descriptors), isolate);
2641a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  int split_nof = split_map->NumberOfOwnDescriptors();
2642e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_NE(old_nof, split_nof);
2643f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
2644f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  split_map->DeprecateTarget(
2645a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      old_descriptors->GetKey(split_nof), *new_descriptors);
2646f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
26479259716434187c932704601f700375e53d865de8rossberg@chromium.org  if (FLAG_trace_generalization) {
2648e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2649e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    PropertyDetails new_details = new_descriptors->GetDetails(modify_index);
2650e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<HeapType> old_field_type = (old_details.type() == FIELD)
2651e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        ? handle(old_descriptors->GetFieldType(modify_index), isolate)
2652e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        : HeapType::Constant(handle(old_descriptors->GetValue(modify_index),
2653e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                    isolate), isolate);
2654e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<HeapType> new_field_type = (new_details.type() == FIELD)
2655e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        ? handle(new_descriptors->GetFieldType(modify_index), isolate)
2656e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        : HeapType::Constant(handle(new_descriptors->GetValue(modify_index),
2657e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                    isolate), isolate);
2658528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    old_map->PrintGeneralization(
2659a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        stdout, "", modify_index, split_nof, old_nof,
2660e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        old_details.type() == CONSTANT && store_mode == FORCE_FIELD,
2661e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        old_details.representation(), new_details.representation(),
2662e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        *old_field_type, *new_field_type);
266357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
266457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
2665f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  // Add missing transitions.
2666528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<Map> new_map = split_map;
2667a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  for (int i = split_nof; i < old_nof; ++i) {
2668a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    new_map = CopyInstallDescriptors(new_map, i, new_descriptors);
2669f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
2670f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  new_map->set_owns_descriptors(true);
2671f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  return new_map;
2672f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
2673f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
26747c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
2675db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org// Generalize the representation of all FIELD descriptors.
2676db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.orgHandle<Map> Map::GeneralizeAllFieldRepresentations(
2677e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<Map> map) {
2678db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  Handle<DescriptorArray> descriptors(map->instance_descriptors());
2679e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) {
2680e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    if (descriptors->GetDetails(i).type() == FIELD) {
2681e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      map = GeneralizeRepresentation(map, i, Representation::Tagged(),
2682e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                     HeapType::Any(map->GetIsolate()),
2683e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                     FORCE_FIELD);
2684db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org    }
2685db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  }
2686db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  return map;
2687db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org}
2688db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org
2689db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org
2690a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org// static
26919d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.orgMaybeHandle<Map> Map::TryUpdate(Handle<Map> map) {
2692113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  Handle<Map> proto_map(map);
2693113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  while (proto_map->prototype()->IsJSObject()) {
2694113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org    Handle<JSObject> holder(JSObject::cast(proto_map->prototype()));
2695113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org    proto_map = Handle<Map>(holder->map());
2696a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if (proto_map->is_deprecated() && JSObject::TryMigrateInstance(holder)) {
2697a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      proto_map = Handle<Map>(holder->map());
2698a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    }
2699113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  }
27009d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  return TryUpdateInternal(map);
2701113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org}
2702bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org
2703bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org
2704a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org// static
27059d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.orgHandle<Map> Map::Update(Handle<Map> map) {
2706a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  if (!map->is_deprecated()) return map;
27079d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  return GeneralizeRepresentation(map, 0, Representation::None(),
27089d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                                  HeapType::None(map->GetIsolate()),
27099d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                                  ALLOW_AS_CONSTANT);
27109d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org}
27119d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org
27129d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org
27139d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org// static
27149d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.orgMaybeHandle<Map> Map::TryUpdateInternal(Handle<Map> old_map) {
2715113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  DisallowHeapAllocation no_allocation;
2716a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  DisallowDeoptimization no_deoptimization(old_map->GetIsolate());
2717113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org
2718a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  if (!old_map->is_deprecated()) return old_map;
2719bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org
2720bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  // Check the state of the root map.
2721a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Map* root_map = old_map->FindRootMap();
2722a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>();
2723a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  int root_nof = root_map->NumberOfOwnDescriptors();
2724bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org
2725a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  int old_nof = old_map->NumberOfOwnDescriptors();
2726a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  DescriptorArray* old_descriptors = old_map->instance_descriptors();
2727bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org
2728a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Map* new_map = root_map;
2729a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  for (int i = root_nof; i < old_nof; ++i) {
2730a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    int j = new_map->SearchTransition(old_descriptors->GetKey(i));
2731a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if (j == TransitionArray::kNotFound) return MaybeHandle<Map>();
2732a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    new_map = new_map->GetTransition(j);
2733a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    DescriptorArray* new_descriptors = new_map->instance_descriptors();
2734bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org
2735a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyDetails new_details = new_descriptors->GetDetails(i);
2736a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyDetails old_details = old_descriptors->GetDetails(i);
2737a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    if (old_details.attributes() != new_details.attributes() ||
2738a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        !old_details.representation().fits_into(new_details.representation())) {
2739a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      return MaybeHandle<Map>();
2740a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    }
2741a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyType new_type = new_details.type();
2742a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    PropertyType old_type = old_details.type();
2743a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    Object* new_value = new_descriptors->GetValue(i);
2744a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    Object* old_value = old_descriptors->GetValue(i);
2745a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    switch (new_type) {
2746a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      case FIELD:
2747a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        if ((old_type == FIELD &&
2748a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org             !HeapType::cast(old_value)->NowIs(HeapType::cast(new_value))) ||
2749a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org            (old_type == CONSTANT &&
2750a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org             !HeapType::cast(new_value)->NowContains(old_value)) ||
2751a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org            (old_type == CALLBACKS &&
2752a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org             !HeapType::Any()->Is(HeapType::cast(new_value)))) {
2753a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          return MaybeHandle<Map>();
2754a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        }
2755a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        break;
2756a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org
2757a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      case CONSTANT:
2758a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      case CALLBACKS:
2759a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        if (old_type != new_type || old_value != new_value) {
2760a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org          return MaybeHandle<Map>();
2761a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        }
2762a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        break;
2763a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org
2764a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      case NORMAL:
2765a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org        UNREACHABLE();
2766a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    }
2767a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  }
2768a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>();
2769a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  return handle(new_map);
2770bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org}
2771bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org
2772bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org
2773474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgMaybeHandle<Object> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
2774474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                                         Handle<Object> value) {
2775750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // TODO(rossberg): Support symbols in the API.
2776474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (it->name()->IsSymbol()) return value;
2777474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2778474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  Handle<String> name_string = Handle<String>::cast(it->name());
2779f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org  Handle<JSObject> holder = it->GetHolder<JSObject>();
2780474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor());
2781474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (interceptor->setter()->IsUndefined()) return MaybeHandle<Object>();
2782474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2783474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  LOG(it->isolate(),
2784474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      ApiNamedPropertyAccess("interceptor-named-set", *holder, *name_string));
2785474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  PropertyCallbackArguments args(it->isolate(), interceptor->data(), *holder,
2786474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                 *holder);
2787474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  v8::NamedPropertySetterCallback setter =
2788474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter());
2789474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  v8::Handle<v8::Value> result = args.Call(
2790474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      setter, v8::Utils::ToLocal(name_string), v8::Utils::ToLocal(value));
2791474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
2792474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (!result.IsEmpty()) return value;
2793474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2794474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  return MaybeHandle<Object>();
279543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
279643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
279743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
279851e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.orgMaybeHandle<Object> Object::SetProperty(Handle<Object> object,
279951e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org                                        Handle<Name> name, Handle<Object> value,
280051e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org                                        StrictMode strict_mode,
280151e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org                                        StoreFromKeyed store_mode) {
2802474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  LookupIterator it(object, name);
280351e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org  return SetProperty(&it, value, strict_mode, store_mode);
2804474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org}
2805474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2806474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2807474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgMaybeHandle<Object> Object::SetProperty(LookupIterator* it,
2808474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                        Handle<Object> value,
2809474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                        StrictMode strict_mode,
2810474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                        StoreFromKeyed store_mode) {
2811474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // Make sure that the top context does not change when doing callbacks or
2812474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // interceptor calls.
2813474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  AssertNoContextChange ncc(it->isolate());
2814474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2815474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  bool done = false;
2816474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  for (; it->IsFound(); it->Next()) {
2817474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    switch (it->state()) {
2818474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      case LookupIterator::NOT_FOUND:
2819474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        UNREACHABLE();
2820474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2821474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      case LookupIterator::ACCESS_CHECK:
2822474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        // TODO(verwaest): Remove the distinction. This is mostly bogus since we
2823474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        // don't know whether we'll want to fetch attributes or call a setter
2824474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        // until we find the property.
2825474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        if (it->HasAccess(v8::ACCESS_SET)) break;
2826474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        return JSObject::SetPropertyWithFailedAccessCheck(it, value,
2827474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                                          strict_mode);
2828474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2829474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      case LookupIterator::JSPROXY:
2830e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        if (it->HolderIsReceiverOrHiddenPrototype()) {
2831f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org          return JSProxy::SetPropertyWithHandler(it->GetHolder<JSProxy>(),
2832474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                                 it->GetReceiver(), it->name(),
2833474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                                 value, strict_mode);
2834474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        } else {
2835474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          // TODO(verwaest): Use the MaybeHandle to indicate result.
2836474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          bool has_result = false;
2837474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          MaybeHandle<Object> maybe_result =
2838474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org              JSProxy::SetPropertyViaPrototypesWithHandler(
2839f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org                  it->GetHolder<JSProxy>(), it->GetReceiver(), it->name(),
2840f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org                  value, strict_mode, &has_result);
2841474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          if (has_result) return maybe_result;
2842474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          done = true;
2843474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        }
2844474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        break;
2845474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2846474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      case LookupIterator::INTERCEPTOR:
2847e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        if (it->HolderIsReceiverOrHiddenPrototype()) {
2848474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          MaybeHandle<Object> maybe_result =
2849474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org              JSObject::SetPropertyWithInterceptor(it, value);
2850474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          if (!maybe_result.is_null()) return maybe_result;
2851474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          if (it->isolate()->has_pending_exception()) return maybe_result;
2852474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        } else {
2853474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          Maybe<PropertyAttributes> maybe_attributes =
2854474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org              JSObject::GetPropertyAttributesWithInterceptor(
2855f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org                  it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
2856eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org          if (!maybe_attributes.has_value) return MaybeHandle<Object>();
2857eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org          done = maybe_attributes.value != ABSENT;
2858474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          if (done && (maybe_attributes.value & READ_ONLY) != 0) {
2859474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org            return WriteToReadOnlyProperty(it, value, strict_mode);
2860474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          }
2861474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        }
2862474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        break;
2863474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
28641af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      case LookupIterator::ACCESSOR:
2865474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        if (it->property_details().IsReadOnly()) {
2866474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          return WriteToReadOnlyProperty(it, value, strict_mode);
2867474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        }
28681af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        if (it->HolderIsReceiverOrHiddenPrototype() ||
28691af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org            !it->GetAccessors()->IsDeclaredAccessorInfo()) {
28701af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value,
28711af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org                                         it->GetHolder<JSObject>(),
28721af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org                                         it->GetAccessors(), strict_mode);
28731af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        }
28741af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        done = true;
28751af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        break;
28761af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org
28771af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      case LookupIterator::DATA:
28781af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        if (it->property_details().IsReadOnly()) {
28791af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          return WriteToReadOnlyProperty(it, value, strict_mode);
28801af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        }
28811af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        if (it->HolderIsReceiverOrHiddenPrototype()) {
28821af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          return SetDataProperty(it, value);
2883474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        }
2884474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        done = true;
2885474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        break;
2886a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
2887a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      case LookupIterator::TRANSITION:
2888a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        done = true;
2889a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        break;
2890474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    }
2891474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2892474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    if (done) break;
2893474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  }
2894474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2895a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // If the receiver is the JSGlobalObject, the store was contextual. In case
2896a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // the property did not exist yet on the global object itself, we have to
2897a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // throw a reference error in strict mode.
2898a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  if (it->GetReceiver()->IsJSGlobalObject() && strict_mode == STRICT) {
2899a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    Handle<Object> args[1] = {it->name()};
2900ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    THROW_NEW_ERROR(it->isolate(),
2901ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                    NewReferenceError("not_defined", HandleVector(args, 1)),
2902ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                    Object);
2903a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  }
2904a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
2905474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  return AddDataProperty(it, value, NONE, strict_mode, store_mode);
2906474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org}
2907474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2908474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2909474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgMaybeHandle<Object> Object::WriteToReadOnlyProperty(LookupIterator* it,
2910474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                                    Handle<Object> value,
2911474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                                    StrictMode strict_mode) {
2912474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (strict_mode != STRICT) return value;
2913474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2914474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  Handle<Object> args[] = {it->name(), it->GetReceiver()};
2915ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  THROW_NEW_ERROR(it->isolate(),
2916ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                  NewTypeError("strict_read_only_property",
2917ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                               HandleVector(args, arraysize(args))),
2918ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                  Object);
2919474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org}
2920474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2921474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2922a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgHandle<Object> Object::SetDataProperty(LookupIterator* it,
2923a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                                       Handle<Object> value) {
2924474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // Proxies are handled on the WithHandler path. Other non-JSObjects cannot
2925474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // have own properties.
2926474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
2927474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2928474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // Store on the holder which may be hidden behind the receiver.
2929e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(it->HolderIsReceiverOrHiddenPrototype());
2930474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2931474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // Old value for the observation change record.
2932474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // Fetch before transforming the object since the encoding may become
2933474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // incompatible with what's cached in |it|.
2934474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  bool is_observed =
2935474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      receiver->map()->is_observed() &&
2936474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      !it->name().is_identical_to(it->factory()->hidden_string());
2937474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  MaybeHandle<Object> maybe_old;
2938474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (is_observed) maybe_old = it->GetDataValue();
2939474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2940474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // Possibly migrate to the most up-to-date map that will be able to store
2941474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // |value| under it->name().
2942474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  it->PrepareForDataProperty(value);
2943474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2944474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // Write the property value.
2945474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  it->WriteDataValue(value);
2946474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2947474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // Send the change record if there are observers.
2948474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (is_observed && !value->SameValue(*maybe_old.ToHandleChecked())) {
2949474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    JSObject::EnqueueChangeRecord(receiver, "update", it->name(),
2950474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                  maybe_old.ToHandleChecked());
2951474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  }
2952474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2953474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  return value;
2954474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org}
2955474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2956474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2957474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgMaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
2958474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                            Handle<Object> value,
2959474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                            PropertyAttributes attributes,
2960474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                            StrictMode strict_mode,
2961474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                            StoreFromKeyed store_mode) {
2962e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!it->GetReceiver()->IsJSProxy());
296351e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org  if (!it->GetReceiver()->IsJSObject()) {
296451e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org    // TODO(verwaest): Throw a TypeError with a more specific message.
296551e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org    return WriteToReadOnlyProperty(it, value, strict_mode);
296651e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org  }
2967a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
2968a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  Handle<JSObject> receiver = it->GetStoreTarget();
2969474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2970474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
2971474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // instead. If the prototype is Null, the proxy is detached.
2972a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  if (receiver->IsJSGlobalProxy()) return value;
2973474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2974a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // Possibly migrate to the most up-to-date map that will be able to store
2975a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // |value| under it->name() with |attributes|.
2976a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  it->PrepareTransitionToDataProperty(value, attributes, store_mode);
2977a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  if (it->state() != LookupIterator::TRANSITION) {
2978474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    if (strict_mode == SLOPPY) return value;
2979474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2980474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    Handle<Object> args[1] = {it->name()};
2981ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    THROW_NEW_ERROR(it->isolate(),
2982ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                    NewTypeError("object_not_extensible",
2983ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                 HandleVector(args, arraysize(args))),
2984ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                    Object);
2985474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  }
2986a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  it->ApplyTransitionToDataProperty();
2987474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2988474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // TODO(verwaest): Encapsulate dictionary handling better.
2989474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (receiver->map()->is_dictionary_map()) {
2990474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    // TODO(verwaest): Probably should ensure this is done beforehand.
2991474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    it->InternalizeName();
2992474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    JSObject::AddSlowProperty(receiver, it->name(), value, attributes);
2993474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  } else {
2994474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    // Write the property value.
2995474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    it->WriteDataValue(value);
2996474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  }
2997474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
2998474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // Send the change record if there are observers.
2999474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (receiver->map()->is_observed() &&
3000474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      !it->name().is_identical_to(it->factory()->hidden_string())) {
3001474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    JSObject::EnqueueChangeRecord(receiver, "add", it->name(),
3002474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                  it->factory()->the_hole_value());
3003753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  }
3004474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
3005474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  return value;
300643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
300743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
300843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30099e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes(
3010b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<JSObject> object,
3011c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org    uint32_t index,
3012b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<Object> value,
3013c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org    bool* found,
3014486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    StrictMode strict_mode) {
3015b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Isolate *isolate = object->GetIsolate();
30169bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  for (PrototypeIterator iter(isolate, object); !iter.IsAtEnd();
30179bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org       iter.Advance()) {
30189bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
3019b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      return JSProxy::SetPropertyViaPrototypesWithHandler(
30209bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org          Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), object,
3021b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org          isolate->factory()->Uint32ToString(index),  // name
30229bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org          value, strict_mode, found);
3023b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    }
30249bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    Handle<JSObject> js_proto =
30259bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
3026b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (!js_proto->HasDictionaryElements()) {
30277b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      continue;
30280b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    }
3029b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary());
303086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org    int entry = dictionary->FindEntry(index);
3031f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    if (entry != SeededNumberDictionary::kNotFound) {
3032bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      PropertyDetails details = dictionary->DetailsAt(entry);
3033bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      if (details.type() == CALLBACKS) {
3034d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com        *found = true;
3035528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        Handle<Object> structure(dictionary->ValueAt(entry), isolate);
3036b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        return SetElementWithCallback(object, structure, index, value, js_proto,
3037b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                      strict_mode);
3038bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      }
3039bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
3040bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
3041d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  *found = false;
3042b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  return isolate->factory()->the_hole_value();
3043bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org}
3044bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
3045528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
304633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.orgvoid Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
3047202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  // Only supports adding slack to owned descriptors.
3048e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(map->owns_descriptors());
3049202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org
305033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  Handle<DescriptorArray> descriptors(map->instance_descriptors());
3051202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  int old_size = map->NumberOfOwnDescriptors();
305233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  if (slack <= descriptors->NumberOfSlackDescriptors()) return;
305333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
3054202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
3055202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      descriptors, old_size, slack);
3056202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org
3057202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  if (old_size == 0) {
3058202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    map->set_instance_descriptors(*new_descriptors);
3059202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    return;
3060202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  }
3061202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org
3062202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  // If the source descriptors had an enum cache we copy it. This ensures
3063202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  // that the maps to which we push the new descriptor array back can rely
3064202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  // on a cache always being available once it is set. If the map has more
3065202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  // enumerated descriptors than available in the original cache, the cache
3066202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  // will be lazily replaced by the extended cache when needed.
3067202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  if (descriptors->HasEnumCache()) {
3068202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    new_descriptors->CopyEnumCacheFrom(*descriptors);
3069202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  }
3070202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org
3071202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  // Replace descriptors by new_descriptors in all maps that share it.
3072202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  map->GetHeap()->incremental_marking()->RecordWrites(*descriptors);
3073202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org
3074202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Map* walk_map;
3075202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  for (Object* current = map->GetBackPointer();
3076202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org       !current->IsUndefined();
3077202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org       current = walk_map->GetBackPointer()) {
3078202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    walk_map = Map::cast(current);
3079202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    if (walk_map->instance_descriptors() != *descriptors) break;
3080202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    walk_map->set_instance_descriptors(*new_descriptors);
308133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  }
308233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
308389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  map->set_instance_descriptors(*new_descriptors);
308433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org}
308533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
308633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
30873d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgtemplate<class T>
30883d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgstatic int AppendUniqueCallbacks(NeanderArray* callbacks,
30893d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                                 Handle<typename T::Array> array,
30903d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                                 int valid_descriptors) {
30913d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  int nof_callbacks = callbacks->length();
3092129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
30933d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  Isolate* isolate = array->GetIsolate();
3094750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Ensure the keys are unique names before writing them into the
30954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // instance descriptor. Since it may cause a GC, it has to be done before we
3096129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  // temporarily put the heap in an invalid state while appending descriptors.
3097129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  for (int i = 0; i < nof_callbacks; ++i) {
30983d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks->get(i)));
30993d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    if (entry->name()->IsUniqueName()) continue;
31003d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    Handle<String> key =
3101f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        isolate->factory()->InternalizeString(
31023d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org            Handle<String>(String::cast(entry->name())));
31033d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    entry->set_name(*key);
3104129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  }
3105129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
3106129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  // Fill in new callback descriptors.  Process the callbacks from
3107129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  // back to front so that the last callback with a given name takes
3108129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  // precedence over previously added callbacks with that name.
3109129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  for (int i = nof_callbacks - 1; i >= 0; i--) {
31105b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks->get(i)));
31115b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    Handle<Name> key(Name::cast(entry->name()));
3112129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    // Check if a descriptor with this name already exists before writing.
31133d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    if (!T::Contains(key, entry, valid_descriptors, array)) {
31143d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org      T::Insert(key, entry, valid_descriptors, array);
31153d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org      valid_descriptors++;
3116129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org    }
3117129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  }
3118129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
31193d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  return valid_descriptors;
31203d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org}
31213d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
31223d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgstruct DescriptorArrayAppender {
31233d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  typedef DescriptorArray Array;
31245b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  static bool Contains(Handle<Name> key,
31255b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                       Handle<AccessorInfo> entry,
31263d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                       int valid_descriptors,
31273d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                       Handle<DescriptorArray> array) {
31285b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    DisallowHeapAllocation no_gc;
31295b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    return array->Search(*key, valid_descriptors) != DescriptorArray::kNotFound;
31303d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  }
31315b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  static void Insert(Handle<Name> key,
31325b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                     Handle<AccessorInfo> entry,
31333d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                     int valid_descriptors,
31343d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                     Handle<DescriptorArray> array) {
31355b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    DisallowHeapAllocation no_gc;
31363d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    CallbacksDescriptor desc(key, entry, entry->property_attributes());
31373d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    array->Append(&desc);
31383d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  }
31393d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org};
31403d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
31413d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
31423d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgstruct FixedArrayAppender {
31433d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  typedef FixedArray Array;
31445b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  static bool Contains(Handle<Name> key,
31455b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                       Handle<AccessorInfo> entry,
31463d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                       int valid_descriptors,
31473d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                       Handle<FixedArray> array) {
31483d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    for (int i = 0; i < valid_descriptors; i++) {
31495b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      if (*key == AccessorInfo::cast(array->get(i))->name()) return true;
31503d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    }
31513d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    return false;
31523d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  }
31535b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  static void Insert(Handle<Name> key,
31545b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                     Handle<AccessorInfo> entry,
31553d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                     int valid_descriptors,
31563d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                     Handle<FixedArray> array) {
31575b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    DisallowHeapAllocation no_gc;
31585b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    array->set(valid_descriptors, *entry);
31593d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  }
31603d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org};
31613d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
31623d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
31633d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid Map::AppendCallbackDescriptors(Handle<Map> map,
31643d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                                    Handle<Object> descriptors) {
31653d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  int nof = map->NumberOfOwnDescriptors();
31663d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  Handle<DescriptorArray> array(map->instance_descriptors());
31673d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  NeanderArray callbacks(descriptors);
3168e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(array->NumberOfSlackDescriptors() >= callbacks.length());
31693d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  nof = AppendUniqueCallbacks<DescriptorArrayAppender>(&callbacks, array, nof);
317033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  map->SetNumberOfOwnDescriptors(nof);
3171129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org}
3172129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
3173129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
31743d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgint AccessorInfo::AppendUnique(Handle<Object> descriptors,
31753d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                               Handle<FixedArray> array,
31763d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                               int valid_descriptors) {
31773d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  NeanderArray callbacks(descriptors);
3178e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(array->length() >= callbacks.length() + valid_descriptors);
31793d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  return AppendUniqueCallbacks<FixedArrayAppender>(&callbacks,
31803d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                                                   array,
31813d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                                                   valid_descriptors);
31823d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org}
31833d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
31843d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
3185394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comstatic bool ContainsMap(MapHandleList* maps, Handle<Map> map) {
3186e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!map.is_null());
3187394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  for (int i = 0; i < maps->length(); ++i) {
3188394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (!maps->at(i).is_null() && maps->at(i).is_identical_to(map)) return true;
3189394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
3190394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return false;
3191394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
3192394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
3193394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
3194394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comtemplate <class T>
3195394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comstatic Handle<T> MaybeNull(T* p) {
3196394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (p == NULL) return Handle<T>::null();
3197394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return Handle<T>(p);
3198394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
3199394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
3200394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
3201394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Map> Map::FindTransitionedMap(MapHandleList* candidates) {
3202830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ElementsKind kind = elements_kind();
3203830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  Handle<Map> transitioned_map = Handle<Map>::null();
3204830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  Handle<Map> current_map(this);
3205830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  bool packed = IsFastPackedElementsKind(kind);
3206830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (IsTransitionableFastElementsKind(kind)) {
3207830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    while (CanTransitionToMoreGeneralFastElementsKind(kind, false)) {
3208830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      kind = GetNextMoreGeneralFastElementsKind(kind, false);
3209830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      Handle<Map> maybe_transitioned_map =
32107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          MaybeNull(current_map->LookupElementsTransitionMap(kind));
3211830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      if (maybe_transitioned_map.is_null()) break;
3212830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      if (ContainsMap(candidates, maybe_transitioned_map) &&
3213830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org          (packed || !IsFastPackedElementsKind(kind))) {
3214830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        transitioned_map = maybe_transitioned_map;
3215830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        if (!IsFastPackedElementsKind(kind)) packed = false;
3216830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      }
3217830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      current_map = maybe_transitioned_map;
3218830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    }
3219830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  }
3220830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  return transitioned_map;
3221394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
3222394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
3223830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org
32247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgstatic Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) {
32257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Map* current_map = map;
3226895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  int target_kind =
3227895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      IsFastElementsKind(to_kind) || IsExternalArrayElementsKind(to_kind)
3228895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      ? to_kind
3229895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      : TERMINAL_FAST_ELEMENTS_KIND;
32305091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org
3231011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  // Support for legacy API: SetIndexedPropertiesTo{External,Pixel}Data
3232011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  // allows to change elements from arbitrary kind to any ExternalArray
3233011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  // elements kind. Satisfy its requirements, checking whether we already
3234011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  // have the cached transition.
3235895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  if (IsExternalArrayElementsKind(to_kind) &&
3236895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      !IsFixedTypedArrayElementsKind(map->elements_kind())) {
3237011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    if (map->HasElementsTransition()) {
3238011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org        Map* next_map = map->elements_transition_map();
3239011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org        if (next_map->elements_kind() == to_kind) return next_map;
3240011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    }
3241895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    return map;
3242895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  }
32435091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org
3244895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  ElementsKind kind = map->elements_kind();
3245895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  while (kind != target_kind) {
3246895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    kind = GetNextTransitionElementsKind(kind);
324799aa490225c81012235659d9a183226b286178c8yangguo@chromium.org    if (!current_map->HasElementsTransition()) return current_map;
324899aa490225c81012235659d9a183226b286178c8yangguo@chromium.org    current_map = current_map->elements_transition_map();
3249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3250895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
3251895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  if (to_kind != kind && current_map->HasElementsTransition()) {
3252e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(to_kind == DICTIONARY_ELEMENTS);
32535091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org    Map* next_map = current_map->elements_transition_map();
325499aa490225c81012235659d9a183226b286178c8yangguo@chromium.org    if (next_map->elements_kind() == to_kind) return next_map;
32555091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org  }
3256895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
3257e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(current_map->elements_kind() == target_kind);
32587028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  return current_map;
3259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
32627028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgMap* Map::LookupElementsTransitionMap(ElementsKind to_kind) {
32635091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org  Map* to_map = FindClosestElementsTransition(this, to_kind);
32645091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org  if (to_map->elements_kind() == to_kind) return to_map;
32657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  return NULL;
3266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3269906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.orgbool Map::IsMapInArrayPrototypeChain() {
3270906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  Isolate* isolate = GetIsolate();
3271906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  if (isolate->initial_array_prototype()->map() == this) {
3272906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    return true;
3273906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  }
3274906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
3275906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  if (isolate->initial_object_prototype()->map() == this) {
3276906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    return true;
3277906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  }
3278906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
3279906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  return false;
3280906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org}
3281906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
3282906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
32835b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgstatic Handle<Map> AddMissingElementsTransitions(Handle<Map> map,
32845b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                                 ElementsKind to_kind) {
3285e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsTransitionElementsKind(map->elements_kind()));
3286830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org
32875b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Map> current_map = map;
3288830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org
3289895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  ElementsKind kind = map->elements_kind();
3290e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  if (!map->is_prototype_map()) {
3291e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    while (kind != to_kind && !IsTerminalElementsKind(kind)) {
3292e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      kind = GetNextTransitionElementsKind(kind);
3293e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      current_map =
3294e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          Map::CopyAsElementsKind(current_map, kind, INSERT_TRANSITION);
3295e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    }
3296b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
3297b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
32985091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org  // In case we are exiting the fast elements kind system, just add the map in
32995091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org  // the end.
3300895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  if (kind != to_kind) {
33015b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    current_map = Map::CopyAsElementsKind(
33025b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org        current_map, to_kind, INSERT_TRANSITION);
33035091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org  }
33045091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org
3305e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(current_map->elements_kind() == to_kind);
33067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  return current_map;
3307b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org}
3308b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
3309b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
3310af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.orgHandle<Map> Map::TransitionElementsTo(Handle<Map> map,
3311af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org                                      ElementsKind to_kind) {
3312af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  ElementsKind from_kind = map->elements_kind();
3313af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  if (from_kind == to_kind) return map;
33145b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org
3315af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  Isolate* isolate = map->GetIsolate();
33165b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Context* native_context = isolate->context()->native_context();
33175b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Object* maybe_array_maps = native_context->js_array_maps();
33185b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  if (maybe_array_maps->IsFixedArray()) {
33195b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    DisallowHeapAllocation no_gc;
33205b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
3321af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    if (array_maps->get(from_kind) == *map) {
33225b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      Object* maybe_transitioned_map = array_maps->get(to_kind);
33235b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      if (maybe_transitioned_map->IsMap()) {
33245b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org        return handle(Map::cast(maybe_transitioned_map));
33255b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      }
33265b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    }
33275b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  }
33285b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org
3329af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  return TransitionElementsToSlow(map, to_kind);
3330394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
3331394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
3332394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
3333af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.orgHandle<Map> Map::TransitionElementsToSlow(Handle<Map> map,
3334af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org                                          ElementsKind to_kind) {
3335af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  ElementsKind from_kind = map->elements_kind();
3336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
33377028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (from_kind == to_kind) {
3338af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    return map;
3339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
33417028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  bool allow_store_transition =
3342e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org      // Only remember the map transition if there is not an already existing
33437028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      // non-matching element transition.
334431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      !map->IsUndefined() && !map->is_dictionary_map() &&
3345895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      IsTransitionElementsKind(from_kind);
33465091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org
33475091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org  // Only store fast element maps in ascending generality.
33485091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org  if (IsFastElementsKind(to_kind)) {
33495091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org    allow_store_transition &=
33505091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org        IsTransitionableFastElementsKind(from_kind) &&
33515091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org        IsMoreGeneralElementsKindTransition(from_kind, to_kind);
33525091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org  }
33537028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
33547028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (!allow_store_transition) {
3355af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION);
33567979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  }
33577979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
3358af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  return Map::AsElementsKind(map, to_kind);
3359e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
3360e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
3361b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
33622904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org// static
33632904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgHandle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) {
33645b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Map> closest_map(FindClosestElementsTransition(*map, kind));
3365e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
3366e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (closest_map->elements_kind() == kind) {
33677028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    return closest_map;
33687979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  }
33697979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
3370e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return AddMissingElementsTransitions(closest_map, kind);
33717979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org}
33727979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
33737979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
3374af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.orgHandle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
3375af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org                                               ElementsKind to_kind) {
3376af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  Handle<Map> map(object->map());
3377af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  return Map::TransitionElementsTo(map, to_kind);
3378af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org}
3379af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
3380af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
3381eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgMaybe<bool> JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy,
3382eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                            Handle<Name> name) {
3383528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Isolate* isolate = proxy->GetIsolate();
3384717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
3385f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3386eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  if (name->IsSymbol()) return maybe(false);
3387f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
3388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<Object> args[] = { name };
33899e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<Object> result;
33909e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
3391eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      isolate, result, CallTrap(proxy, "has", isolate->derived_has_trap(),
3392fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                                arraysize(args), args),
3393eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      Maybe<bool>());
3394717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
3395eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  return maybe(result->BooleanValue());
3396717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org}
3397717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
3398717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
3399474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgMaybeHandle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy,
3400474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                                    Handle<Object> receiver,
3401474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                                    Handle<Name> name,
3402474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                                    Handle<Object> value,
3403474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                                    StrictMode strict_mode) {
3404528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Isolate* isolate = proxy->GetIsolate();
3405d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
3406f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3407528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (name->IsSymbol()) return value;
3408f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
3409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<Object> args[] = { receiver, name, value };
34109e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  RETURN_ON_EXCEPTION(
34119e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      isolate,
34129e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      CallTrap(proxy,
34139e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org               "set",
34149e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org               isolate->derived_set_trap(),
3415fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org               arraysize(args),
34169e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org               args),
34179e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      Object);
3418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3419528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  return value;
3420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
34239e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
3424474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name,
3425474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    Handle<Object> value, StrictMode strict_mode, bool* done) {
3426528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Isolate* isolate = proxy->GetIsolate();
3427528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<Object> handler(proxy->handler(), isolate);  // Trap might morph proxy.
34287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
3429f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3430f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (name->IsSymbol()) {
3431f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    *done = false;
3432528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return isolate->factory()->the_hole_value();
3433f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
3434f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
34357028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  *done = true;  // except where redefined...
3436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<Object> args[] = { name };
34379e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<Object> result;
34389e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
34399e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      isolate, result,
34409e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      CallTrap(proxy,
34419e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org               "getPropertyDescriptor",
34429e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org               Handle<Object>(),
3443fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org               arraysize(args),
34449e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org               args),
34459e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      Object);
3446d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
34477028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (result->IsUndefined()) {
34487028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    *done = false;
3449528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return isolate->factory()->the_hole_value();
34507028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
3451d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
34527028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // Emulate [[GetProperty]] semantics for proxies.
34537028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Handle<Object> argv[] = { result };
34542ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> desc;
34552ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
34562ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, desc,
34572ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Execution::Call(isolate,
34582ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                      isolate->to_complete_property_descriptor(),
34592ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                      result,
3460fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                      arraysize(argv),
34612ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                      argv),
34622ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Object);
34637028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
34647028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // [[GetProperty]] requires to check that all properties are configurable.
34654a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> configurable_name =
34664a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      isolate->factory()->InternalizeOneByteString(
34672c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org          STATIC_CHAR_VECTOR("configurable_"));
34682ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> configurable =
34692ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Object::GetProperty(desc, configurable_name).ToHandleChecked();
3470e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(configurable->IsBoolean());
34717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (configurable->IsFalse()) {
34722c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    Handle<String> trap = isolate->factory()->InternalizeOneByteString(
34732c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        STATIC_CHAR_VECTOR("getPropertyDescriptor"));
34747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    Handle<Object> args[] = { handler, trap, name };
3475ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    THROW_NEW_ERROR(isolate, NewTypeError("proxy_prop_not_configurable",
3476ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                          HandleVector(args, arraysize(args))),
3477ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                    Object);
34787028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
3479e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(configurable->IsTrue());
34807028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
34817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // Check for DataDescriptor.
34827028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Handle<String> hasWritable_name =
34834a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      isolate->factory()->InternalizeOneByteString(
34842c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org          STATIC_CHAR_VECTOR("hasWritable_"));
34852ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> hasWritable =
34862ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Object::GetProperty(desc, hasWritable_name).ToHandleChecked();
3487e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(hasWritable->IsBoolean());
34887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (hasWritable->IsTrue()) {
34892c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    Handle<String> writable_name = isolate->factory()->InternalizeOneByteString(
34902c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        STATIC_CHAR_VECTOR("writable_"));
34912ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> writable =
34922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        Object::GetProperty(desc, writable_name).ToHandleChecked();
3493e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(writable->IsBoolean());
34947028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    *done = writable->IsFalse();
3495528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    if (!*done) return isolate->factory()->the_hole_value();
3496486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    if (strict_mode == SLOPPY) return value;
34977028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    Handle<Object> args[] = { name, receiver };
3498ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property",
3499ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                          HandleVector(args, arraysize(args))),
3500ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                    Object);
3501400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  }
3502400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org
35037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // We have an AccessorDescriptor.
35042c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  Handle<String> set_name =
35052c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_"));
35062ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked();
35077028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (!setter->IsUndefined()) {
35087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    // TODO(rossberg): nicer would be to cast to some JSCallable here...
3509528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return SetPropertyWithDefinedSetter(
3510528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        receiver, Handle<JSReceiver>::cast(setter), value);
35117028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
35127028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
3513486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (strict_mode == SLOPPY) return value;
35147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Handle<Object> args2[] = { name, proxy };
3515ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  THROW_NEW_ERROR(isolate, NewTypeError("no_setter_in_callback",
3516ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                        HandleVector(args2, arraysize(args2))),
3517ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                  Object);
3518d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org}
3519d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
3520d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
35219e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSProxy::DeletePropertyWithHandler(
35228fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) {
35238fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  Isolate* isolate = proxy->GetIsolate();
352484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
3525f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3526ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (name->IsSymbol()) return isolate->factory()->false_value();
3527f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
3528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<Object> args[] = { name };
35299e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<Object> result;
35309e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
35319e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      isolate, result,
35329e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      CallTrap(proxy,
35339e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org               "delete",
35349e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org               Handle<Object>(),
3535fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org               arraysize(args),
35369e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org               args),
35379e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      Object);
353884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
35399faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  bool result_bool = result->BooleanValue();
35409faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  if (mode == STRICT_DELETION && !result_bool) {
35418fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    Handle<Object> handler(proxy->handler(), isolate);
35424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Handle<String> trap_name = isolate->factory()->InternalizeOneByteString(
35432c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        STATIC_CHAR_VECTOR("delete"));
3544ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org    Handle<Object> args[] = { handler, trap_name };
3545ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    THROW_NEW_ERROR(isolate, NewTypeError("handler_failed",
3546ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                          HandleVector(args, arraysize(args))),
3547ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                    Object);
354884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  }
3549ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return isolate->factory()->ToBoolean(result_bool);
355084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org}
355184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
355284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org
35539e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSProxy::DeleteElementWithHandler(
35548fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    Handle<JSProxy> proxy, uint32_t index, DeleteMode mode) {
35558fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  Isolate* isolate = proxy->GetIsolate();
3556c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<String> name = isolate->factory()->Uint32ToString(index);
35578fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  return JSProxy::DeletePropertyWithHandler(proxy, name, mode);
3558c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3559c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3560c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3561eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgMaybe<PropertyAttributes> JSProxy::GetPropertyAttributesWithHandler(
3562eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name) {
3563381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  Isolate* isolate = proxy->GetIsolate();
356484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  HandleScope scope(isolate);
3565d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
3566f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3567eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  if (name->IsSymbol()) return maybe(ABSENT);
3568f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
3569c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<Object> args[] = { name };
35709e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<Object> result;
35719e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
35729e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      isolate, result,
3573eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      proxy->CallTrap(proxy, "getPropertyDescriptor", Handle<Object>(),
3574fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                      arraysize(args), args),
3575eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      Maybe<PropertyAttributes>());
3576c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3577eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  if (result->IsUndefined()) return maybe(ABSENT);
3578c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3579a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Handle<Object> argv[] = { result };
35802ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> desc;
35812ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
35822ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, desc,
3583eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      Execution::Call(isolate, isolate->to_complete_property_descriptor(),
3584fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                      result, arraysize(argv), argv),
3585eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      Maybe<PropertyAttributes>());
3586c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3587c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Convert result to PropertyAttributes.
35884a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> enum_n = isolate->factory()->InternalizeOneByteString(
35892c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      STATIC_CHAR_VECTOR("enumerable_"));
35902ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> enumerable;
3591eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, enumerable,
3592eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                   Object::GetProperty(desc, enum_n),
3593eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                   Maybe<PropertyAttributes>());
35944a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> conf_n = isolate->factory()->InternalizeOneByteString(
35952c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      STATIC_CHAR_VECTOR("configurable_"));
35962ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> configurable;
3597eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, configurable,
3598eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                   Object::GetProperty(desc, conf_n),
3599eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                   Maybe<PropertyAttributes>());
36004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> writ_n = isolate->factory()->InternalizeOneByteString(
36012c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      STATIC_CHAR_VECTOR("writable_"));
36022ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> writable;
3603eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, writable,
3604eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                   Object::GetProperty(desc, writ_n),
3605eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                   Maybe<PropertyAttributes>());
3606ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (!writable->BooleanValue()) {
3607ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<String> set_n = isolate->factory()->InternalizeOneByteString(
36082c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        STATIC_CHAR_VECTOR("set_"));
36092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> setter;
3610eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, setter,
3611eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                     Object::GetProperty(desc, set_n),
3612eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                     Maybe<PropertyAttributes>());
3613ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    writable = isolate->factory()->ToBoolean(!setter->IsUndefined());
3614ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
3615c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3616c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (configurable->IsFalse()) {
3617381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org    Handle<Object> handler(proxy->handler(), isolate);
36184a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Handle<String> trap = isolate->factory()->InternalizeOneByteString(
36192c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        STATIC_CHAR_VECTOR("getPropertyDescriptor"));
3620394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Handle<Object> args[] = { handler, trap, name };
3621ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    Handle<Object> error;
3622ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    MaybeHandle<Object> maybe_error = isolate->factory()->NewTypeError(
3623fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org        "proxy_prop_not_configurable", HandleVector(args, arraysize(args)));
3624ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
3625eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    return maybe(NONE);
3626d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  }
3627d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
3628c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int attributes = NONE;
36299faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  if (!enumerable->BooleanValue()) attributes |= DONT_ENUM;
36309faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  if (!configurable->BooleanValue()) attributes |= DONT_DELETE;
36319faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  if (!writable->BooleanValue()) attributes |= READ_ONLY;
3632eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  return maybe(static_cast<PropertyAttributes>(attributes));
3633c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3634c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3635d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
3636eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgMaybe<PropertyAttributes> JSProxy::GetElementAttributeWithHandler(
3637eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    Handle<JSProxy> proxy, Handle<JSReceiver> receiver, uint32_t index) {
3638381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  Isolate* isolate = proxy->GetIsolate();
3639c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Handle<String> name = isolate->factory()->Uint32ToString(index);
36401845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  return GetPropertyAttributesWithHandler(proxy, receiver, name);
3641d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org}
3642d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
3643d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
36448fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.orgvoid JSProxy::Fix(Handle<JSProxy> proxy) {
36458fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  Isolate* isolate = proxy->GetIsolate();
3646717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
3647c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Save identity hash.
3648057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Handle<Object> hash(proxy->GetIdentityHash(), isolate);
3649c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
36508fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  if (proxy->IsJSFunctionProxy()) {
36518fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    isolate->factory()->BecomeJSFunction(proxy);
365234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    // Code will be set on the JavaScript side.
365334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  } else {
36548fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    isolate->factory()->BecomeJSObject(proxy);
365534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
3656e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(proxy->IsJSObject());
3657c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3658c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Inherit identity, if it was present.
36598fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  if (hash->IsSmi()) {
3660057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    JSObject::SetIdentityHash(Handle<JSObject>::cast(proxy),
3661057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org                              Handle<Smi>::cast(hash));
3662c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3663717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org}
3664717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
3665717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
36669e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy,
36679e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                      const char* name,
36689e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                      Handle<Object> derived,
36699e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                      int argc,
36709e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                      Handle<Object> argv[]) {
36719e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Isolate* isolate = proxy->GetIsolate();
36729e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<Object> handler(proxy->handler(), isolate);
3673c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
36744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<String> trap_name = isolate->factory()->InternalizeUtf8String(name);
3675202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<Object> trap;
3676202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
3677202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      isolate, trap,
3678202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      Object::GetPropertyOrElement(handler, trap_name),
3679202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      Object);
3680c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3681c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (trap->IsUndefined()) {
3682c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (derived.is_null()) {
3683c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Handle<Object> args[] = { handler, trap_name };
3684ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      THROW_NEW_ERROR(isolate,
3685ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                      NewTypeError("handler_trap_missing",
3686ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                   HandleVector(args, arraysize(args))),
3687ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                      Object);
3688c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
3689c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    trap = Handle<Object>(derived);
3690c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3691c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
36922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return Execution::Call(isolate, trap, handler, argc, argv);
3693c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3694c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3695717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
3696528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
3697e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->map()->inobject_properties() == map->inobject_properties());
3698528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  ElementsKind obj_kind = object->map()->elements_kind();
3699528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  ElementsKind map_kind = map->elements_kind();
3700528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (map_kind != obj_kind) {
3701528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    ElementsKind to_kind = map_kind;
3702528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    if (IsMoreGeneralElementsKindTransition(map_kind, obj_kind) ||
3703528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        IsDictionaryElementsKind(obj_kind)) {
3704528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      to_kind = obj_kind;
3705528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    }
3706528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    if (IsDictionaryElementsKind(to_kind)) {
3707528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      NormalizeElements(object);
3708528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    } else {
3709528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      TransitionElementsKind(object, to_kind);
3710528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    }
37115b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    map = Map::AsElementsKind(map, to_kind);
3712528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
371397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  JSObject::MigrateToMap(object, map);
3714f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
3715f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
3716f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
3717528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid JSObject::MigrateInstance(Handle<JSObject> object) {
3718528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<Map> original_map(object->map());
37199d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  Handle<Map> map = Map::Update(original_map);
37209d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  map->set_migration_target(true);
37219d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  MigrateToMap(object, map);
3722528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (FLAG_trace_migration) {
37239d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org    object->PrintInstanceMigration(stdout, *original_map, *map);
3724528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
3725e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
3726e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
3727e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
3728a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org// static
3729a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.orgbool JSObject::TryMigrateInstance(Handle<JSObject> object) {
3730a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Isolate* isolate = object->GetIsolate();
3731a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  DisallowDeoptimization no_deoptimization(isolate);
3732a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Handle<Map> original_map(object->map(), isolate);
3733a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  Handle<Map> new_map;
37349d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  if (!Map::TryUpdate(original_map).ToHandle(&new_map)) {
3735a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    return false;
3736a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  }
3737113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  JSObject::MigrateToMap(object, new_map);
37383d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  if (FLAG_trace_migration) {
37393d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    object->PrintInstanceMigration(stdout, *original_map, object->map());
37403d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  }
3741a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  return true;
37422f877ace3ac6432b1ce44abd553cd3ff97321680hpayer@chromium.org}
37432f877ace3ac6432b1ce44abd553cd3ff97321680hpayer@chromium.org
37442f877ace3ac6432b1ce44abd553cd3ff97321680hpayer@chromium.org
37459fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgvoid JSObject::MigrateToNewProperty(Handle<JSObject> object,
37469fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                    Handle<Map> map,
37479fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                    Handle<Object> value) {
37489fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  JSObject::MigrateToMap(object, map);
37499fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (map->GetLastDescriptorDetails().type() != FIELD) return;
37509fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  object->WriteToField(map->LastAdded(), *value);
37519fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
375297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
37539fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
37549fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgvoid JSObject::WriteToField(int descriptor, Object* value) {
37559fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  DisallowHeapAllocation no_gc;
37569fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
37579fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  DescriptorArray* desc = map()->instance_descriptors();
37589fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  PropertyDetails details = desc->GetDetails(descriptor);
37599fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
3760e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(details.type() == FIELD);
37619fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
3762e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor);
376397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  if (details.representation().IsDouble()) {
376497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    // Nothing more to be done.
37659fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (value->IsUninitialized()) return;
3766e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index));
3767e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(box->IsMutableHeapNumber());
376897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    box->set_value(value->Number());
376997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  } else {
3770e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    FastPropertyAtPut(index, value);
377197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
37729259716434187c932704601f700375e53d865de8rossberg@chromium.org}
37739259716434187c932704601f700375e53d865de8rossberg@chromium.org
37749259716434187c932704601f700375e53d865de8rossberg@chromium.org
37759d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.orgvoid JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name,
37769d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                           Handle<Object> value,
37779d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                           PropertyAttributes attributes) {
37789aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
37799aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
37805de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#ifdef DEBUG
37815de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  uint32_t index;
3782e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsJSProxy());
3783e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!name->AsArrayIndex(&index));
3784c86c97af7bb97954519ad08b7f093128dbe45c77machenbach@chromium.org  Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it);
3785e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(maybe.has_value);
3786e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!it.IsFound());
37875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  DCHECK(object->map()->is_extensible() ||
37885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org         name.is_identical_to(it.isolate()->factory()->hidden_string()));
37895de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#endif
37905e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  AddDataProperty(&it, value, attributes, STRICT,
37915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                  CERTAINLY_NOT_STORE_FROM_KEYED).Check();
37925de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org}
37935de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
37945de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
37959bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org// Reconfigures a property to a data property with attributes, even if it is not
37969bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org// reconfigurable.
3797fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgMaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
3798f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    Handle<JSObject> object,
3799528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<Name> name,
3800f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    Handle<Object> value,
38011fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    PropertyAttributes attributes,
3802e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    ExecutableAccessorInfoHandling handling) {
3803e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!value->IsTheHole());
38046474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
38055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  bool is_observed = object->map()->is_observed() &&
38065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                     *name != it.isolate()->heap()->hidden_string();
38075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  for (; it.IsFound(); it.Next()) {
38085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    switch (it.state()) {
38095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      case LookupIterator::INTERCEPTOR:
3810a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      case LookupIterator::JSPROXY:
3811a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      case LookupIterator::NOT_FOUND:
3812a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      case LookupIterator::TRANSITION:
38135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        UNREACHABLE();
3814528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
38155e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      case LookupIterator::ACCESS_CHECK:
38165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        if (!it.isolate()->MayNamedAccess(object, name, v8::ACCESS_SET)) {
38175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY);
38185e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        }
38195e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        break;
3820528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
38211af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      case LookupIterator::ACCESSOR: {
38225e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        PropertyDetails details = it.property_details();
38235e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Handle<Object> old_value = it.isolate()->factory()->the_hole_value();
38241af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        // Ensure the context isn't changed after calling into accessors.
38251af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        AssertNoContextChange ncc(it.isolate());
382665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
38271af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        Handle<Object> accessors = it.GetAccessors();
382865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
38291af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        if (is_observed && accessors->IsAccessorInfo()) {
38301af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          ASSIGN_RETURN_ON_EXCEPTION(
38311af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org              it.isolate(), old_value,
38321af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org              GetPropertyWithAccessor(it.GetReceiver(), it.name(),
38331af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org                                      it.GetHolder<JSObject>(), accessors),
38341af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org              Object);
38351af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        }
38361f410f9a9c4fbd4270749af64b477df87b753158mstarzinger@chromium.org
38371af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        // Special handling for ExecutableAccessorInfo, which behaves like a
38381af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        // data property.
38391af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        if (handling == DONT_FORCE_FIELD &&
38401af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org            accessors->IsExecutableAccessorInfo()) {
38411af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          Handle<Object> result;
38421af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          ASSIGN_RETURN_ON_EXCEPTION(
38431af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org              it.isolate(), result,
38441af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org              JSObject::SetPropertyWithAccessor(it.GetReceiver(), it.name(),
38451af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org                                                value, it.GetHolder<JSObject>(),
38461af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org                                                accessors, STRICT),
38471af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org              Object);
38481af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          DCHECK(result->SameValue(*value));
38491af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org
38501af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          if (details.attributes() == attributes) {
38511af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org            // Regular property update if the attributes match.
38521af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org            if (is_observed && !old_value->SameValue(*value)) {
38531af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org              // If we are setting the prototype of a function and are
38541af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org              // observed, don't send change records because the prototype
38551af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org              // handles that itself.
38561af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org              if (!object->IsJSFunction() ||
38571af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org                  !Name::Equals(it.isolate()->factory()->prototype_string(),
38581af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org                                name) ||
38591af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org                  !Handle<JSFunction>::cast(object)->should_have_prototype()) {
38601af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org                EnqueueChangeRecord(object, "update", name, old_value);
38615e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              }
38621af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org            }
38631af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org            return value;
38641af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          }
3865e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
38661af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          // Reconfigure the accessor if attributes mismatch.
38671af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor(
38681af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org              it.isolate(), Handle<ExecutableAccessorInfo>::cast(accessors));
38691af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          new_data->set_property_attributes(attributes);
38701af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          // By clearing the setter we don't have to introduce a lookup to
38711af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          // the setter, simply make it unavailable to reflect the
38721af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          // attributes.
38731af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          if (attributes & READ_ONLY) new_data->clear_setter();
38741af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          SetPropertyCallback(object, name, new_data, attributes);
38751af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          if (is_observed) {
38761af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org            if (old_value->SameValue(*value)) {
38771af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org              old_value = it.isolate()->factory()->the_hole_value();
38785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            }
38791af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org            EnqueueChangeRecord(object, "reconfigure", name, old_value);
38801af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          }
38811af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          return value;
38821af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        }
38835d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
38841af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        it.ReconfigureDataProperty(value, attributes);
38851af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        it.PrepareForDataProperty(value);
38861af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        it.WriteDataValue(value);
38871af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org
38881af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        if (is_observed) {
38891af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          if (old_value->SameValue(*value)) {
38901af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org            old_value = it.isolate()->factory()->the_hole_value();
38915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
38921af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          EnqueueChangeRecord(object, "reconfigure", name, old_value);
38931af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        }
3894e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
38951af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        return value;
38961af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      }
38971af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org
38981af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      case LookupIterator::DATA: {
38991af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        PropertyDetails details = it.property_details();
39001af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        Handle<Object> old_value = it.isolate()->factory()->the_hole_value();
39011af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        // Regular property update if the attributes match.
39021af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        if (details.attributes() == attributes) {
39031af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          return SetDataProperty(&it, value);
39045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        }
39051af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        // Reconfigure the data property if the attributes mismatch.
39061af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        if (is_observed) old_value = it.GetDataValue();
3907e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
39085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        it.ReconfigureDataProperty(value, attributes);
39095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        it.PrepareForDataProperty(value);
39105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        it.WriteDataValue(value);
39115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
39125e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        if (is_observed) {
39135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (old_value->SameValue(*value)) {
39145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            old_value = it.isolate()->factory()->the_hole_value();
3915e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org          }
39165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          EnqueueChangeRecord(object, "reconfigure", name, old_value);
3917e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org        }
3918e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
39195e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        return value;
3920e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      }
3921e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
3922e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
3923e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
39245e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return AddDataProperty(&it, value, attributes, STRICT,
39255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                         CERTAINLY_NOT_STORE_FROM_KEYED);
392643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
392743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
392843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
39291845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgMaybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
39301845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    Handle<JSObject> holder,
39311845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    Handle<Object> receiver,
39321845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    Handle<Name> name) {
3933750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // TODO(rossberg): Support symbols in the API.
3934eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  if (name->IsSymbol()) return maybe(ABSENT);
3935750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
39361845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  Isolate* isolate = holder->GetIsolate();
3937dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  HandleScope scope(isolate);
3938ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
393943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make sure that the top context does not change when doing
394043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // callbacks or interceptor calls.
3941fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  AssertNoContextChange ncc(isolate);
394243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
39431845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor());
3944381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  PropertyCallbackArguments args(
39451845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      isolate, interceptor->data(), *receiver, *holder);
394643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!interceptor->query()->IsUndefined()) {
3947662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    v8::NamedPropertyQueryCallback query =
3948662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org        v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query());
3949ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    LOG(isolate,
39501845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        ApiNamedPropertyAccess("interceptor-named-has", *holder, *name));
39511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    v8::Handle<v8::Integer> result =
3952381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org        args.Call(query, v8::Utils::ToLocal(Handle<String>::cast(name)));
395343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!result.IsEmpty()) {
3954e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(result->IsInt32());
3955eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      return maybe(static_cast<PropertyAttributes>(result->Int32Value()));
395643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
395743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (!interceptor->getter()->IsUndefined()) {
3958662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    v8::NamedPropertyGetterCallback getter =
3959662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org        v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
3960ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    LOG(isolate,
39611845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        ApiNamedPropertyAccess("interceptor-named-get-has", *holder, *name));
39621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    v8::Handle<v8::Value> result =
3963381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org        args.Call(getter, v8::Utils::ToLocal(Handle<String>::cast(name)));
3964eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    if (!result.IsEmpty()) return maybe(DONT_ENUM);
396543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
3966eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org
3967eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>());
3968eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  return maybe(ABSENT);
396943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
397043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
397143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3972eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgMaybe<PropertyAttributes> JSReceiver::GetOwnPropertyAttributes(
39731845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    Handle<JSReceiver> object, Handle<Name> name) {
39741845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // Check whether the name is an array index.
397541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  uint32_t index = 0;
39761845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  if (object->IsJSObject() && name->AsArrayIndex(&index)) {
39771845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    return GetOwnElementAttribute(object, index);
397843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
39796474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  LookupIterator it(object, name, LookupIterator::HIDDEN);
39801845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  return GetPropertyAttributes(&it);
398143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
398243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
398343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3984eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgMaybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
3985eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    LookupIterator* it) {
39861845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  for (; it->IsFound(); it->Next()) {
39871845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    switch (it->state()) {
39881845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      case LookupIterator::NOT_FOUND:
3989a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      case LookupIterator::TRANSITION:
39909a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        UNREACHABLE();
39911845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      case LookupIterator::JSPROXY:
39921845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        return JSProxy::GetPropertyAttributesWithHandler(
3993f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org            it->GetHolder<JSProxy>(), it->GetReceiver(), it->name());
39941845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      case LookupIterator::INTERCEPTOR: {
39951845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        Maybe<PropertyAttributes> result =
39961845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org            JSObject::GetPropertyAttributesWithInterceptor(
3997f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org                it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
3998eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org        if (!result.has_value) return result;
3999eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org        if (result.value != ABSENT) return result;
40001845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        break;
40011845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      }
40021845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      case LookupIterator::ACCESS_CHECK:
40031845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        if (it->HasAccess(v8::ACCESS_HAS)) break;
40041845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        return JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
40051af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      case LookupIterator::ACCESSOR:
40061af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      case LookupIterator::DATA:
40071af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        return maybe(it->property_details().attributes());
400843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
400943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
4010eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  return maybe(ABSENT);
401143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
401243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
401343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4014eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgMaybe<PropertyAttributes> JSObject::GetElementAttributeWithReceiver(
4015eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index,
40168d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    bool check_prototype) {
4017381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
4018e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4019e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Check access rights if needed.
4020381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  if (object->IsAccessCheckNeeded()) {
4021c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) {
4022c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
4023eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>());
4024eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      return maybe(ABSENT);
4025e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
4026e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4027e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4028381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  if (object->IsJSGlobalProxy()) {
402993720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    PrototypeIterator iter(isolate, object);
4030eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    if (iter.IsAtEnd()) return maybe(ABSENT);
4031e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
4032381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org    return JSObject::GetElementAttributeWithReceiver(
403393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), receiver,
403493720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        index, check_prototype);
4035e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4036e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4037e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Check for lookup interceptor except when bootstrapping.
4038381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  if (object->HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) {
4039381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org    return JSObject::GetElementAttributeWithInterceptor(
40408d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        object, receiver, index, check_prototype);
4041e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4042e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4043e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return GetElementAttributeWithoutInterceptor(
40448d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      object, receiver, index, check_prototype);
4045e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
4046e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4047e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4048eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgMaybe<PropertyAttributes> JSObject::GetElementAttributeWithInterceptor(
4049eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index,
40508d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    bool check_prototype) {
4051381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
4052dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  HandleScope scope(isolate);
4053dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
4054e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Make sure that the top context does not change when doing
4055e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // callbacks or interceptor calls.
4056fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  AssertNoContextChange ncc(isolate);
4057dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
4058381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
4059381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  PropertyCallbackArguments args(
4060381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org      isolate, interceptor->data(), *receiver, *object);
4061e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (!interceptor->query()->IsUndefined()) {
4062662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    v8::IndexedPropertyQueryCallback query =
4063662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org        v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
4064e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    LOG(isolate,
4065381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org        ApiIndexedPropertyAccess("interceptor-indexed-has", *object, index));
40661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    v8::Handle<v8::Integer> result = args.Call(query, index);
4067e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    if (!result.IsEmpty())
4068eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      return maybe(static_cast<PropertyAttributes>(result->Int32Value()));
4069e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else if (!interceptor->getter()->IsUndefined()) {
4070662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    v8::IndexedPropertyGetterCallback getter =
4071662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org        v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
4072e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    LOG(isolate,
4073381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org        ApiIndexedPropertyAccess(
4074381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org            "interceptor-indexed-get-has", *object, index));
40751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    v8::Handle<v8::Value> result = args.Call(getter, index);
4076eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    if (!result.IsEmpty()) return maybe(NONE);
4077e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4078e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4079381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  return GetElementAttributeWithoutInterceptor(
40808d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org       object, receiver, index, check_prototype);
4081e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
4082e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4083e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4084eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgMaybe<PropertyAttributes> JSObject::GetElementAttributeWithoutInterceptor(
4085eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index,
40868d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    bool check_prototype) {
4087381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  PropertyAttributes attr = object->GetElementsAccessor()->GetAttributes(
40888f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      receiver, object, index);
4089eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  if (attr != ABSENT) return maybe(attr);
4090e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
409171fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  // Handle [] on String objects.
4092381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  if (object->IsStringObjectWithCharacterAt(index)) {
4093eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    return maybe(static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE));
4094e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4095e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4096eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  if (!check_prototype) return maybe(ABSENT);
4097e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
409893720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  PrototypeIterator iter(object->GetIsolate(), object);
409993720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
4100e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // We need to follow the spec and simulate a call to [[GetOwnProperty]].
4101381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org    return JSProxy::GetElementAttributeWithHandler(
410293720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), receiver,
410393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        index);
4104e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4105eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  if (iter.IsAtEnd()) return maybe(ABSENT);
4106381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  return GetElementAttributeWithReceiver(
410793720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org      Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), receiver,
410893720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org      index, true);
410943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
411043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
411143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4112c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.orgHandle<NormalizedMapCache> NormalizedMapCache::New(Isolate* isolate) {
4113c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  Handle<FixedArray> array(
4114c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org      isolate->factory()->NewFixedArray(kEntries, TENURED));
4115c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  return Handle<NormalizedMapCache>::cast(array);
4116c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org}
4117c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
4118c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
4119c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.orgMaybeHandle<Map> NormalizedMapCache::Get(Handle<Map> fast_map,
4120c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org                                         PropertyNormalizationMode mode) {
4121c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  DisallowHeapAllocation no_gc;
4122c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  Object* value = FixedArray::get(GetIndex(fast_map));
4123c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  if (!value->IsMap() ||
4124c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org      !Map::cast(value)->EquivalentToForNormalization(*fast_map, mode)) {
4125c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    return MaybeHandle<Map>();
412665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  }
4127c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  return handle(Map::cast(value));
4128c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org}
41294a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
413065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
4131c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.orgvoid NormalizedMapCache::Set(Handle<Map> fast_map,
4132c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org                             Handle<Map> normalized_map) {
4133c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  DisallowHeapAllocation no_gc;
4134e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(normalized_map->is_dictionary_map());
4135c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  FixedArray::set(GetIndex(fast_map), *normalized_map);
413665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}
413765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
413865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
413965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgvoid NormalizedMapCache::Clear() {
414065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  int entries = length();
414165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  for (int i = 0; i != entries; i++) {
414265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    set_undefined(i);
414365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  }
414465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}
414565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
414665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
41474a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.orgvoid HeapObject::UpdateMapCodeCache(Handle<HeapObject> object,
41484a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                                    Handle<Name> name,
41494a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                                    Handle<Code> code) {
4150c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  Handle<Map> map(object->map());
4151c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  Map::UpdateCodeCache(map, name, code);
415265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}
415365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
415465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
4155f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid JSObject::NormalizeProperties(Handle<JSObject> object,
4156f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                                   PropertyNormalizationMode mode,
4157f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                                   int expected_additional_properties) {
4158528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (!object->HasFastProperties()) return;
415943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
416008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Handle<Map> map(object->map());
416108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Handle<Map> new_map = Map::Normalize(map, mode);
416208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org
416308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  MigrateFastToSlow(object, new_map, expected_additional_properties);
416408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org}
416508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org
416608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org
416708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgvoid JSObject::MigrateFastToSlow(Handle<JSObject> object,
416808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                 Handle<Map> new_map,
416908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                 int expected_additional_properties) {
41700b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // The global object is always normalized.
4171e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsGlobalObject());
417283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  // JSGlobalProxy must never be normalized
4173e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsJSGlobalProxy());
417483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
4175528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Isolate* isolate = object->GetIsolate();
4176528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(isolate);
4177528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<Map> map(object->map());
4178ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
41790b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // Allocate new content.
4180528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  int real_size = map->NumberOfOwnDescriptors();
418133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  int property_count = real_size;
41820b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  if (expected_additional_properties > 0) {
41830b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    property_count += expected_additional_properties;
41840b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  } else {
41850b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    property_count += 2;  // Make space for two more properties.
41860b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  }
4187528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<NameDictionary> dictionary =
4188865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      NameDictionary::New(isolate, property_count);
418943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4190528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<DescriptorArray> descs(map->instance_descriptors());
419106ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  for (int i = 0; i < real_size; i++) {
4192ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    PropertyDetails details = descs->GetDetails(i);
419343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    switch (details.type()) {
4194fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      case CONSTANT: {
4195528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        Handle<Name> key(descs->GetKey(i));
4196528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        Handle<Object> value(descs->GetConstant(i), isolate);
419757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        PropertyDetails d = PropertyDetails(
419857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org            details.attributes(), NORMAL, i + 1);
4199f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org        dictionary = NameDictionary::Add(dictionary, key, value, d);
420043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
420143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
420243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      case FIELD: {
4203528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        Handle<Name> key(descs->GetKey(i));
4204e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        FieldIndex index = FieldIndex::ForDescriptor(*map, i);
4205528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        Handle<Object> value(
4206e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org            object->RawFastPropertyAt(index), isolate);
420758a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org        if (details.representation().IsDouble()) {
4208e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(value->IsMutableHeapNumber());
420958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org          Handle<HeapNumber> old = Handle<HeapNumber>::cast(value);
421058a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org          value = isolate->factory()->NewHeapNumber(old->value());
421158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org        }
421257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        PropertyDetails d =
421357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org            PropertyDetails(details.attributes(), NORMAL, i + 1);
4214f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org        dictionary = NameDictionary::Add(dictionary, key, value, d);
421543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
421643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
421743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      case CALLBACKS: {
4218528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        Handle<Name> key(descs->GetKey(i));
4219528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        Handle<Object> value(descs->GetCallbacksObject(i), isolate);
422057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        PropertyDetails d = PropertyDetails(
422157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org            details.attributes(), CALLBACKS, i + 1);
4222f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org        dictionary = NameDictionary::Add(dictionary, key, value, d);
422343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
422443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
4225c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      case NORMAL:
42269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com        UNREACHABLE();
4227c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org        break;
422843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
422943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
423043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
423143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Copy the next enumeration index from instance descriptor.
423206ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  dictionary->SetNextEnumerationIndex(real_size + 1);
423343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4234528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // From here on we cannot fail and we shouldn't GC anymore.
4235528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  DisallowHeapAllocation no_allocation;
423665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
423765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  // Resize the object in the heap if necessary.
423865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  int new_instance_size = new_map->instance_size();
4239528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  int instance_size_delta = map->instance_size() - new_instance_size;
4240e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(instance_size_delta >= 0);
42412b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org
42422b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org  if (instance_size_delta > 0) {
42432b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org    Heap* heap = isolate->heap();
42442b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org    heap->CreateFillerObjectAt(object->address() + new_instance_size,
42452b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org                               instance_size_delta);
42462b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org    heap->AdjustLiveBytes(object->address(), -instance_size_delta,
42472b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org                          Heap::FROM_MUTATOR);
42482b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org  }
4249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
425063a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  // We are storing the new map using release store after creating a filler for
425163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  // the left-over space to avoid races with the sweeper thread.
425263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  object->synchronized_set_map(*new_map);
425363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
4254528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  object->set_properties(*dictionary);
425543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4256528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  isolate->counters()->props_to_dictionary()->Increment();
425743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
425843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
425943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_trace_normalization) {
4260f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    OFStream os(stdout);
4261f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "Object properties have been normalized:\n";
4262f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    object->Print(os);
426343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
426443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
426543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
426643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
426743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
426808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgvoid JSObject::MigrateSlowToFast(Handle<JSObject> object,
426908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                 int unused_property_fields) {
4270528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (object->HasFastProperties()) return;
4271e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsGlobalObject());
42722ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
42732ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Factory* factory = isolate->factory();
42742ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<NameDictionary> dictionary(object->property_dictionary());
42752ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
42762ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Make sure we preserve dictionary representation if there are too many
42772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // descriptors.
42782ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int number_of_elements = dictionary->NumberOfElements();
42792ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (number_of_elements > kMaxNumberOfDescriptors) return;
42802ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
42812ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (number_of_elements != dictionary->NextEnumerationIndex()) {
42822ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    NameDictionary::DoGenerateNewEnumerationIndices(dictionary);
42832ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
42842ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
42852ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int instance_descriptor_length = 0;
42862ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int number_of_fields = 0;
42872ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
42882ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Compute the length of the instance descriptor.
42892ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int capacity = dictionary->Capacity();
42902ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  for (int i = 0; i < capacity; i++) {
42912ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Object* k = dictionary->KeyAt(i);
42922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (dictionary->IsKey(k)) {
42932ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Object* value = dictionary->ValueAt(i);
42942ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      PropertyType type = dictionary->DetailsAt(i).type();
4295e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(type != FIELD);
42962ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      instance_descriptor_length++;
42972ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      if (type == NORMAL && !value->IsJSFunction()) {
42982ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        number_of_fields += 1;
42992ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      }
43002ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    }
43012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
43022ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
43032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int inobject_props = object->map()->inobject_properties();
43042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
43052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Allocate new map.
43062ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
43072ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  new_map->set_dictionary_map(false);
43082ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
43092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (instance_descriptor_length == 0) {
43102ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    DisallowHeapAllocation no_gc;
4311e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK_LE(unused_property_fields, inobject_props);
43122ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    // Transform the object.
43132ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    new_map->set_unused_property_fields(inobject_props);
431408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    object->synchronized_set_map(*new_map);
43152ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    object->set_properties(isolate->heap()->empty_fixed_array());
43162ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    // Check that it really works.
4317e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(object->HasFastProperties());
43182ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    return;
43192ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
43202ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
43212ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Allocate the instance descriptor.
43222ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<DescriptorArray> descriptors = DescriptorArray::Allocate(
43232ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, instance_descriptor_length);
43242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
43252ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int number_of_allocated_fields =
43262ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      number_of_fields + unused_property_fields - inobject_props;
43272ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (number_of_allocated_fields < 0) {
43282ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    // There is enough inobject space for all fields (including unused).
43292ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    number_of_allocated_fields = 0;
43302ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    unused_property_fields = inobject_props - number_of_fields;
43312ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
43322ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
43332ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Allocate the fixed array for the fields.
43342ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<FixedArray> fields = factory->NewFixedArray(
43352ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      number_of_allocated_fields);
43362ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
43372ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Fill in the instance descriptor and the fields.
43382ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int current_offset = 0;
43392ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  for (int i = 0; i < capacity; i++) {
43402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Object* k = dictionary->KeyAt(i);
43412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (dictionary->IsKey(k)) {
43422ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Object* value = dictionary->ValueAt(i);
43432ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Handle<Name> key;
43442ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      if (k->IsSymbol()) {
43452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        key = handle(Symbol::cast(k));
43462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      } else {
43472ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        // Ensure the key is a unique name before writing into the
43482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        // instance descriptor.
43492ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        key = factory->InternalizeString(handle(String::cast(k)));
43502ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      }
43512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
43522ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      PropertyDetails details = dictionary->DetailsAt(i);
43532ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      int enumeration_index = details.dictionary_index();
43542ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      PropertyType type = details.type();
43552ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
43562ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      if (value->IsJSFunction()) {
43572ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        ConstantDescriptor d(key,
43582ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                             handle(value, isolate),
43592ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                             details.attributes());
43602ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        descriptors->Set(enumeration_index - 1, &d);
43612ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      } else if (type == NORMAL) {
43622ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        if (current_offset < inobject_props) {
43632ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          object->InObjectPropertyAtPut(current_offset,
43642ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                        value,
43652ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                        UPDATE_WRITE_BARRIER);
43662ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        } else {
43672ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          int offset = current_offset - inobject_props;
43682ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          fields->set(offset, value);
43692ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        }
43702ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        FieldDescriptor d(key,
43712ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                          current_offset++,
43722ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                          details.attributes(),
43732ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                          // TODO(verwaest): value->OptimalRepresentation();
43742ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                          Representation::Tagged());
43752ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        descriptors->Set(enumeration_index - 1, &d);
43762ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      } else if (type == CALLBACKS) {
43772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        CallbacksDescriptor d(key,
43782ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                              handle(value, isolate),
43792ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                              details.attributes());
43802ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        descriptors->Set(enumeration_index - 1, &d);
43812ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      } else {
43822ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        UNREACHABLE();
43832ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      }
43842ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    }
43852ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
4386e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(current_offset == number_of_fields);
43872ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
43882ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  descriptors->Sort();
43892ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
43902ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  DisallowHeapAllocation no_gc;
43912ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  new_map->InitializeDescriptors(*descriptors);
43922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  new_map->set_unused_property_fields(unused_property_fields);
43932ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
43942ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Transform the object.
439508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  object->synchronized_set_map(*new_map);
43962ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
43972ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  object->set_properties(*fields);
4398e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->IsJSObject());
43992ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
44002ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Check that it really works.
4401e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->HasFastProperties());
440243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
440343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
440443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
440563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.orgvoid JSObject::ResetElements(Handle<JSObject> object) {
440642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
440742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  CHECK(object->map() != isolate->heap()->sloppy_arguments_elements_map());
440842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  if (object->map()->has_dictionary_elements()) {
440942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org    Handle<SeededNumberDictionary> new_elements =
441042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org        SeededNumberDictionary::New(isolate, 0);
441142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org    object->set_elements(*new_elements);
441242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  } else {
441342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org    object->set_elements(object->map()->GetInitialElements());
441442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  }
441563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org}
441663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
441763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
4418fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.orgstatic Handle<SeededNumberDictionary> CopyFastElementsToDictionary(
4419fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    Handle<FixedArrayBase> array,
4420a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    int length,
4421fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    Handle<SeededNumberDictionary> dictionary) {
4422fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  Isolate* isolate = array->GetIsolate();
4423fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  Factory* factory = isolate->factory();
4424a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  bool has_double_elements = array->IsFixedDoubleArray();
4425a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  for (int i = 0; i < length; i++) {
4426fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    Handle<Object> value;
4427a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (has_double_elements) {
4428fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      Handle<FixedDoubleArray> double_array =
4429fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org          Handle<FixedDoubleArray>::cast(array);
4430a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      if (double_array->is_the_hole(i)) {
4431fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        value = factory->the_hole_value();
4432a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      } else {
4433fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        value = factory->NewHeapNumber(double_array->get_scalar(i));
4434a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      }
4435a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    } else {
4436fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      value = handle(Handle<FixedArray>::cast(array)->get(i), isolate);
4437a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    }
4438a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (!value->IsTheHole()) {
4439a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      PropertyDetails details = PropertyDetails(NONE, NORMAL, 0);
4440fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      dictionary =
4441fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org          SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details);
4442a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    }
4443a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
4444a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  return dictionary;
4445a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org}
4446a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
4447a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
4448f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comHandle<SeededNumberDictionary> JSObject::NormalizeElements(
4449f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    Handle<JSObject> object) {
4450e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->HasExternalArrayElements() &&
4451895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org         !object->HasFixedTypedArrayElements());
4452fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  Isolate* isolate = object->GetIsolate();
445340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
44547b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Find the backing store.
4455fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements()));
44567b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  bool is_arguments =
4457fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      (array->map() == isolate->heap()->sloppy_arguments_elements_map());
44587b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (is_arguments) {
4459fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    array = handle(FixedArrayBase::cast(
4460fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        Handle<FixedArray>::cast(array)->get(1)));
44617b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
4462fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  if (array->IsDictionary()) return Handle<SeededNumberDictionary>::cast(array);
44637b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
4464e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->HasFastSmiOrObjectElements() ||
4465fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org         object->HasFastDoubleElements() ||
4466fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org         object->HasFastArgumentsElements());
44677b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Compute the effective length and allocate a new backing store.
4468fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  int length = object->IsJSArray()
4469fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      ? Smi::cast(Handle<JSArray>::cast(object)->length())->value()
44707b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      : array->length();
44712c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  int old_capacity = 0;
44722c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  int used_elements = 0;
4473fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  object->GetElementsCapacityAndUsage(&old_capacity, &used_elements);
4474fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  Handle<SeededNumberDictionary> dictionary =
4475865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      SeededNumberDictionary::New(isolate, used_elements);
44767b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
4477fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  dictionary = CopyFastElementsToDictionary(array, length, dictionary);
447843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
44797b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Switch to using the dictionary as the backing storage for elements.
44807b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (is_arguments) {
4481fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    FixedArray::cast(object->elements())->set(1, *dictionary);
44827b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  } else {
44837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // Set the new map first to satify the elements type assert in
44847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // set_elements().
4485fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    Handle<Map> new_map =
4486fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        JSObject::GetElementsTransitionMap(object, DICTIONARY_ELEMENTS);
4487fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org
4488fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    JSObject::MigrateToMap(object, new_map);
4489fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    object->set_elements(*dictionary);
44907b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
44917b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
4492fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  isolate->counters()->elements_to_dictionary()->Increment();
449343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
449443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
449543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (FLAG_trace_normalization) {
4496f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    OFStream os(stdout);
4497f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "Object elements have been normalized:\n";
4498f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    object->Print(os);
449943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
450043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
450143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4502e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->HasDictionaryElements() ||
4503fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org         object->HasDictionaryArgumentsElements());
45047b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  return dictionary;
450543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
450643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
450743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
450829699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.orgstatic Smi* GenerateIdentityHash(Isolate* isolate) {
45097943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  int hash_value;
45107943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  int attempts = 0;
45117943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  do {
45127943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org    // Generate a random 32-bit hash value but limit range to fit
45137943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org    // within a smi.
4514c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    hash_value = isolate->random_number_generator()->NextInt() & Smi::kMaxValue;
45157943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org    attempts++;
45167943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  } while (hash_value == 0 && attempts < 30);
45177943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  hash_value = hash_value != 0 ? hash_value : 1;  // never return 0
45187943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
4519c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return Smi::FromInt(hash_value);
4520c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
4521c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4522c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4523057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgvoid JSObject::SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash) {
4524e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsJSGlobalProxy());
4525057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Isolate* isolate = object->GetIsolate();
4526057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash);
4527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
4528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
453029699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.orgtemplate<typename ProxyType>
45313c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.orgstatic Handle<Smi> GetOrCreateIdentityHashHelper(Handle<ProxyType> proxy) {
453229699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org  Isolate* isolate = proxy->GetIsolate();
453329699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org
45343c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Handle<Object> maybe_hash(proxy->hash(), isolate);
45353c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  if (maybe_hash->IsSmi()) return Handle<Smi>::cast(maybe_hash);
453629699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org
45373c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Handle<Smi> hash(GenerateIdentityHash(isolate), isolate);
453829699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org  proxy->set_hash(*hash);
453929699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org  return hash;
454029699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org}
454129699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org
454229699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org
4543057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgObject* JSObject::GetIdentityHash() {
45443484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  DisallowHeapAllocation no_gc;
45453484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Isolate* isolate = GetIsolate();
454629699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org  if (IsJSGlobalProxy()) {
454729699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org    return JSGlobalProxy::cast(this)->hash();
454829699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org  }
45493484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Object* stored_value =
45503484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      GetHiddenProperty(isolate->factory()->identity_hash_string());
45513484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  return stored_value->IsSmi()
45523484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      ? stored_value
45533484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      : isolate->heap()->undefined_value();
4554f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
4555f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
4556f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
45573c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.orgHandle<Smi> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) {
455829699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org  if (object->IsJSGlobalProxy()) {
455929699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org    return GetOrCreateIdentityHashHelper(Handle<JSGlobalProxy>::cast(object));
456029699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org  }
4561057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
4562057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Isolate* isolate = object->GetIsolate();
4563c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
45643c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Handle<Object> maybe_hash(object->GetIdentityHash(), isolate);
45653c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  if (maybe_hash->IsSmi()) return Handle<Smi>::cast(maybe_hash);
4566057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
45673c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Handle<Smi> hash(GenerateIdentityHash(isolate), isolate);
456829699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org  SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash);
45697943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  return hash;
45707943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org}
45717943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
45727943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
4573057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgObject* JSProxy::GetIdentityHash() {
4574057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  return this->hash();
45758fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org}
45768fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org
45778fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org
45783c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.orgHandle<Smi> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) {
457929699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org  return GetOrCreateIdentityHashHelper(proxy);
4580c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
4581c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4582c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
45833484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgObject* JSObject::GetHiddenProperty(Handle<Name> key) {
45843484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  DisallowHeapAllocation no_gc;
4585e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(key->IsUniqueName());
4586c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (IsJSGlobalProxy()) {
458729699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org    // JSGlobalProxies store their hash internally.
4588e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(*key != GetHeap()->identity_hash_string());
4589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // For a proxy, use the prototype as target object.
459093720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    PrototypeIterator iter(GetIsolate(), this);
4591c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // If the proxy is detached, return undefined.
459293720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    if (iter.IsAtEnd()) return GetHeap()->the_hole_value();
4593e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(iter.GetCurrent()->IsJSGlobalObject());
459493720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    return JSObject::cast(iter.GetCurrent())->GetHiddenProperty(key);
4595c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
4596e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsJSGlobalProxy());
4597057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Object* inline_value = GetHiddenPropertiesHashTable();
4598000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org
4599000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  if (inline_value->IsSmi()) {
4600000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org    // Handle inline-stored identity hash.
46013484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    if (*key == GetHeap()->identity_hash_string()) {
4602000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org      return inline_value;
4603000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org    } else {
46041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      return GetHeap()->the_hole_value();
4605000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org    }
4606c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
4607000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org
46081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (inline_value->IsUndefined()) return GetHeap()->the_hole_value();
4609000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org
4610000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value);
4611000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  Object* entry = hashtable->Lookup(key);
4612000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  return entry;
4613c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
4614c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4615c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4616057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgHandle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object,
4617750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                           Handle<Name> key,
4618000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org                                           Handle<Object> value) {
4619057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Isolate* isolate = object->GetIsolate();
4620f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
4621e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(key->IsUniqueName());
4622057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  if (object->IsJSGlobalProxy()) {
462329699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org    // JSGlobalProxies store their hash internally.
4624e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(*key != *isolate->factory()->identity_hash_string());
4625c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // For a proxy, use the prototype as target object.
462693720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    PrototypeIterator iter(isolate, object);
4627c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // If the proxy is detached, return undefined.
462893720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    if (iter.IsAtEnd()) return isolate->factory()->undefined_value();
4629e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
463093720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    return SetHiddenProperty(
463193720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key,
463293720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        value);
4633c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
4634e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsJSGlobalProxy());
4635057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
4636057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate);
4637000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org
463889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // If there is no backing store yet, store the identity hash inline.
4639000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  if (value->IsSmi() &&
4640057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org      *key == *isolate->factory()->identity_hash_string() &&
4641000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org      (inline_value->IsUndefined() || inline_value->IsSmi())) {
4642057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    return JSObject::SetHiddenPropertiesHashTable(object, value);
4643c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
4644000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org
4645057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Handle<ObjectHashTable> hashtable =
4646057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org      GetOrCreateHiddenPropertiesHashtable(object);
4647000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org
4648000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  // If it was found, check if the key is already in the dictionary.
4649057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Handle<ObjectHashTable> new_table = ObjectHashTable::Put(hashtable, key,
4650057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org                                                           value);
4651057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  if (*new_table != *hashtable) {
4652c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // If adding the key expanded the dictionary (i.e., Add returned a new
4653c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // dictionary), store it back to the object.
4654057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    SetHiddenPropertiesHashTable(object, new_table);
4655c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
4656057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
4657c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Return this to mark success.
4658057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  return object;
4659c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
4660c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4661c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
46628fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.orgvoid JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) {
46638fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  Isolate* isolate = object->GetIsolate();
4664e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(key->IsUniqueName());
46658fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org
46668fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  if (object->IsJSGlobalProxy()) {
466793720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    PrototypeIterator iter(isolate, object);
466893720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    if (iter.IsAtEnd()) return;
4669e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
467093720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    return DeleteHiddenProperty(
467193720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key);
4672c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
46738fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org
4674057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Object* inline_value = object->GetHiddenPropertiesHashTable();
467589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
4676000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  // We never delete (inline-stored) identity hashes.
4677e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(*key != *isolate->factory()->identity_hash_string());
467889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  if (inline_value->IsUndefined() || inline_value->IsSmi()) return;
4679000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org
46808fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value));
4681196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  bool was_present = false;
4682196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  ObjectHashTable::Remove(hashtable, key, &was_present);
4683c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
4684c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4685c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4686381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.orgbool JSObject::HasHiddenProperties(Handle<JSObject> object) {
4687381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string();
46889aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  LookupIterator it(object, hidden, LookupIterator::OWN_SKIP_INTERCEPTOR);
46892c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it);
46902c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  // Cannot get an exception since the hidden_string isn't accessible to JS.
46912c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  DCHECK(maybe.has_value);
46922c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  return maybe.value != ABSENT;
4693c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
4694c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4695c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4696057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgObject* JSObject::GetHiddenPropertiesHashTable() {
4697e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsJSGlobalProxy());
4698c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (HasFastProperties()) {
4699c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // If the object has fast properties, check whether the first slot
47004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // in the descriptor array matches the hidden string. Since the
4701750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    // hidden strings hash code is zero (and no other name has hash
4702c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // code zero) it will always occupy the first entry if present.
4703c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    DescriptorArray* descriptors = this->map()->instance_descriptors();
470446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    if (descriptors->number_of_descriptors() > 0) {
470546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      int sorted_index = descriptors->GetSortedKeyIndex(0);
47064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() &&
470706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org          sorted_index < map()->NumberOfOwnDescriptors()) {
4708e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(descriptors->GetType(sorted_index) == FIELD);
4709e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(descriptors->GetDetails(sorted_index).representation().
4710057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org               IsCompatibleForLoad(Representation::Tagged()));
4711e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        FieldIndex index = FieldIndex::ForDescriptor(this->map(),
4712e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                                     sorted_index);
4713e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        return this->RawFastPropertyAt(index);
471446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      } else {
4715057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org        return GetHeap()->undefined_value();
471646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      }
4717000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org    } else {
4718057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org      return GetHeap()->undefined_value();
4719c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
4720c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
47213484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    Isolate* isolate = GetIsolate();
4722e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    LookupIterator it(handle(this), isolate->factory()->hidden_string(),
47239aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org                      LookupIterator::OWN_SKIP_INTERCEPTOR);
47246313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org    // Access check is always skipped for the hidden string anyways.
47256313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org    return *GetDataProperty(&it);
4726c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
4727057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org}
4728000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org
4729057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgHandle<ObjectHashTable> JSObject::GetOrCreateHiddenPropertiesHashtable(
4730057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    Handle<JSObject> object) {
4731057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Isolate* isolate = object->GetIsolate();
4732000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org
4733000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  static const int kInitialCapacity = 4;
4734057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate);
4735057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  if (inline_value->IsHashTable()) {
4736057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    return Handle<ObjectHashTable>::cast(inline_value);
4737057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  }
4738057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
4739865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Handle<ObjectHashTable> hashtable = ObjectHashTable::New(
4740865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      isolate, kInitialCapacity, USE_CUSTOM_MINIMUM_CAPACITY);
4741000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org
4742000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  if (inline_value->IsSmi()) {
4743000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org    // We were storing the identity hash inline and now allocated an actual
4744000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org    // dictionary.  Put the identity hash into the new dictionary.
4745057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    hashtable = ObjectHashTable::Put(hashtable,
4746057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org                                     isolate->factory()->identity_hash_string(),
4747057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org                                     inline_value);
4748000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  }
4749000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org
47505e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  SetHiddenPropertiesHashTable(object, hashtable);
4751000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  return hashtable;
4752c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
4753c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4754c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4755057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgHandle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object,
4756057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org                                                      Handle<Object> value) {
4757e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsJSGlobalProxy());
4758057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Isolate* isolate = object->GetIsolate();
47595e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Handle<Name> name = isolate->factory()->hidden_string();
47605e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  SetOwnPropertyIgnoreAttributes(object, name, value, DONT_ENUM).Assert();
4761057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  return object;
4762c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
4763c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4764c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
47658496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.orgMaybeHandle<Object> JSObject::DeletePropertyWithInterceptor(
47665e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    Handle<JSObject> holder, Handle<JSObject> receiver, Handle<Name> name) {
47675e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Isolate* isolate = holder->GetIsolate();
4768ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
4769750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // TODO(rossberg): Support symbols in the API.
47705e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  if (name->IsSymbol()) return MaybeHandle<Object>();
4771750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
47725e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor());
47735e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  if (interceptor->deleter()->IsUndefined()) return MaybeHandle<Object>();
47745e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
47755e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  v8::NamedPropertyDeleterCallback deleter =
47765e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      v8::ToCData<v8::NamedPropertyDeleterCallback>(interceptor->deleter());
47775e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  LOG(isolate,
47785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      ApiNamedPropertyAccess("interceptor-named-delete", *holder, *name));
47795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
47805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                                 *holder);
47815e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  v8::Handle<v8::Boolean> result =
47825e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      args.Call(deleter, v8::Utils::ToLocal(Handle<String>::cast(name)));
47835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
47845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  if (result.IsEmpty()) return MaybeHandle<Object>();
47855e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
47865e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  DCHECK(result->IsBoolean());
47875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
47885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  result_internal->VerifyApiCallResultType();
47895e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // Rebox CustomArguments::kReturnValueOffset before returning.
47905e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return handle(*result_internal, isolate);
479143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
479243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
479343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
47945b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgMaybeHandle<Object> JSObject::DeleteElementWithInterceptor(
47955b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    Handle<JSObject> object,
47965b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    uint32_t index) {
4797dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  Isolate* isolate = object->GetIsolate();
4798dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  Factory* factory = isolate->factory();
4799dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
480043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make sure that the top context does not change when doing
480143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // callbacks or interceptor calls.
4802fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  AssertNoContextChange ncc(isolate);
4803dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
4804dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
4805dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  if (interceptor->deleter()->IsUndefined()) return factory->false_value();
4806662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  v8::IndexedPropertyDeleterCallback deleter =
4807662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter());
4808ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LOG(isolate,
4809dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org      ApiIndexedPropertyAccess("interceptor-indexed-delete", *object, index));
4810dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  PropertyCallbackArguments args(
4811dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org      isolate, interceptor->data(), *object, *object);
48121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  v8::Handle<v8::Boolean> result = args.Call(deleter, index);
48138496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
481443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!result.IsEmpty()) {
4815e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(result->IsBoolean());
4816de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
4817de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    result_internal->VerifyApiCallResultType();
4818dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    // Rebox CustomArguments::kReturnValueOffset before returning.
4819dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    return handle(*result_internal, isolate);
482043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
48215b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  MaybeHandle<Object> delete_result = object->GetElementsAccessor()->Delete(
48227010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org      object, index, NORMAL_DELETION);
4823dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  return delete_result;
482443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
482543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
482643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48275b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgMaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object,
48285b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                            uint32_t index,
48295b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                            DeleteMode mode) {
4830dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  Isolate* isolate = object->GetIsolate();
4831dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  Factory* factory = isolate->factory();
4832f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
48335a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Check access rights if needed.
4834dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  if (object->IsAccessCheckNeeded() &&
4835c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      !isolate->MayIndexedAccess(object, index, v8::ACCESS_DELETE)) {
4836c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE);
48378496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
4838dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    return factory->false_value();
48395a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
48405a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
4841dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  if (object->IsStringObjectWithCharacterAt(index)) {
484289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    if (mode == STRICT_DELETION) {
484389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      // Deleting a non-configurable property in strict mode.
4844dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org      Handle<Object> name = factory->NewNumberFromUint(index);
4845dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org      Handle<Object> args[2] = { name, object };
4846ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      THROW_NEW_ERROR(isolate, NewTypeError("strict_delete_property",
4847ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                            HandleVector(args, 2)),
4848ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                      Object);
484989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    }
4850dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    return factory->false_value();
485189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  }
485289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
4853dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  if (object->IsJSGlobalProxy()) {
485493720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    PrototypeIterator iter(isolate, object);
485593720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    if (iter.IsAtEnd()) return factory->false_value();
4856e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
485793720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    return DeleteElement(
485893720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index,
485993720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        mode);
48605a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
48615a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
4862fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  Handle<Object> old_value;
486383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  bool should_enqueue_change_record = false;
486497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  if (object->map()->is_observed()) {
4865eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    Maybe<bool> maybe = HasOwnElement(object, index);
4866eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    if (!maybe.has_value) return MaybeHandle<Object>();
4867eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    should_enqueue_change_record = maybe.value;
486883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    if (should_enqueue_change_record) {
4869fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      if (!GetOwnElementAccessorPair(object, index).is_null()) {
48704452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org        old_value = Handle<Object>::cast(factory->the_hole_value());
48714452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org      } else {
48722ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        old_value = Object::GetElement(
48732ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org            isolate, object, index).ToHandleChecked();
48744452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org      }
48752abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    }
487643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
48777c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
4878e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Skip interceptor if forcing deletion.
48795b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  MaybeHandle<Object> maybe_result;
4880dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) {
48815b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    maybe_result = DeleteElementWithInterceptor(object, index);
4882e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else {
48835b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    maybe_result = object->GetElementsAccessor()->Delete(object, index, mode);
4884e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
48855b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Object> result;
48865b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object);
4887e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4888eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  if (should_enqueue_change_record) {
4889eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    Maybe<bool> maybe = HasOwnElement(object, index);
4890eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    if (!maybe.has_value) return MaybeHandle<Object>();
4891eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    if (!maybe.value) {
4892eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      Handle<String> name = factory->Uint32ToString(index);
4893eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      EnqueueChangeRecord(object, "delete", name, old_value);
4894eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    }
4895e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4896e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4897dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  return result;
489843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
489943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
490043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49015b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgMaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
49025b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                             Handle<Name> name,
4903e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                                             DeleteMode delete_mode) {
49045a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // ECMA-262, 3rd, 8.6.2.5
4905e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(name->IsName());
49065a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
490741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  uint32_t index = 0;
490843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (name->AsArrayIndex(&index)) {
4909e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    return DeleteElement(object, index, delete_mode);
4910e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4911e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
49125e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // Skip interceptors on FORCE_DELETION.
49135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  LookupIterator::Configuration config =
49146474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      delete_mode == FORCE_DELETION ? LookupIterator::HIDDEN_SKIP_INTERCEPTOR
49156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                    : LookupIterator::HIDDEN;
49165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
49175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  LookupIterator it(object, name, config);
4918e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
491997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  bool is_observed = object->map()->is_observed() &&
49205e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                     *name != it.isolate()->heap()->hidden_string();
49211af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org  Handle<Object> old_value = it.isolate()->factory()->the_hole_value();
4922e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
49235e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  for (; it.IsFound(); it.Next()) {
49245e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    switch (it.state()) {
49255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      case LookupIterator::JSPROXY:
4926a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      case LookupIterator::NOT_FOUND:
4927a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      case LookupIterator::TRANSITION:
49285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        UNREACHABLE();
49295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      case LookupIterator::ACCESS_CHECK:
49305e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        if (it.HasAccess(v8::ACCESS_DELETE)) break;
49315e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        it.isolate()->ReportFailedAccessCheck(it.GetHolder<JSObject>(),
49325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                                              v8::ACCESS_DELETE);
49335e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it.isolate(), Object);
49345e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        return it.isolate()->factory()->false_value();
49355e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      case LookupIterator::INTERCEPTOR: {
49365e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        MaybeHandle<Object> maybe_result =
49375e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            JSObject::DeletePropertyWithInterceptor(it.GetHolder<JSObject>(),
49385e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                                                    object, it.name());
49395e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        // Delete with interceptor succeeded. Return result.
49405e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        if (!maybe_result.is_null()) return maybe_result;
49415e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        // An exception was thrown in the interceptor. Propagate.
49425e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        if (it.isolate()->has_pending_exception()) return maybe_result;
49435e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        break;
49445e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
49451af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      case LookupIterator::DATA:
49461af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        if (is_observed) {
49471af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          old_value = it.GetDataValue();
49481af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        }
49491af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      // Fall through.
49501af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      case LookupIterator::ACCESSOR: {
49515e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        if (delete_mode != FORCE_DELETION && !it.IsConfigurable()) {
49525e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          // Fail if the property is not configurable.
49535e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (delete_mode == STRICT_DELETION) {
49545e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            Handle<Object> args[2] = {name, object};
4955ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org            THROW_NEW_ERROR(it.isolate(),
4956ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                            NewTypeError("strict_delete_property",
4957ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                         HandleVector(args, arraysize(args))),
4958ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                            Object);
49595e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
49605e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          return it.isolate()->factory()->false_value();
49615e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        }
4962e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
49635e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        PropertyNormalizationMode mode = object->map()->is_prototype_map()
49645e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                                             ? KEEP_INOBJECT_PROPERTIES
49655e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                                             : CLEAR_INOBJECT_PROPERTIES;
49665e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Handle<JSObject> holder = it.GetHolder<JSObject>();
49675e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        // TODO(verwaest): Remove this temporary compatibility hack when blink
49685e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        // tests are updated.
49695e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        if (!holder.is_identical_to(object) &&
49705e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) {
49715e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          return it.isolate()->factory()->true_value();
49725e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        }
49735e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        NormalizeProperties(holder, mode, 0);
49745e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Handle<Object> result =
49755e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            DeleteNormalizedProperty(holder, name, delete_mode);
49765e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        ReoptimizeIfPrototype(holder);
49775e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
49785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        if (is_observed) {
49795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          EnqueueChangeRecord(object, "delete", name, old_value);
49805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        }
49815e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
49825e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        return result;
49835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
4984eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    }
4985e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
4986e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
49875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return it.isolate()->factory()->true_value();
498843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
498943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
499043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49919e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object,
49929e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                              uint32_t index,
49939e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                              DeleteMode mode) {
4994ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (object->IsJSProxy()) {
4995ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    return JSProxy::DeleteElementWithHandler(
4996ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        Handle<JSProxy>::cast(object), index, mode);
4997f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  }
4998ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return JSObject::DeleteElement(Handle<JSObject>::cast(object), index, mode);
4999f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
5000f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
5001f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
50029e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object,
50039e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                               Handle<Name> name,
50049e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                               DeleteMode mode) {
5005ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (object->IsJSProxy()) {
5006ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    return JSProxy::DeletePropertyWithHandler(
5007ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        Handle<JSProxy>::cast(object), name, mode);
5008f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  }
5009ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, mode);
5010f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
5011f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
5012f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
50137b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgbool JSObject::ReferencesObjectFromElements(FixedArray* elements,
50147b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                                            ElementsKind kind,
50157b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                                            Object* object) {
5016e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsFastObjectElementsKind(kind) ||
5017c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com         kind == DICTIONARY_ELEMENTS);
5018830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (IsFastObjectElementsKind(kind)) {
50197b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    int length = IsJSArray()
50207b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        ? Smi::cast(JSArray::cast(this)->length())->value()
50217b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        : elements->length();
50227b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    for (int i = 0; i < length; ++i) {
50237b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      Object* element = elements->get(i);
50247b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      if (!element->IsTheHole() && element == object) return true;
50257b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
50267b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  } else {
5027f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    Object* key =
5028f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        SeededNumberDictionary::cast(elements)->SlowReverseLookup(object);
50297b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (!key->IsUndefined()) return true;
50307b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
50317b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  return false;
50327b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org}
50337b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
50347b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
503543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check whether this object references another object.
503643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool JSObject::ReferencesObject(Object* obj) {
5037c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Map* map_of_this = map();
5038c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Heap* heap = GetHeap();
503979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
504043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
504143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Is the object the constructor for this object?
5042c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (map_of_this->constructor() == obj) {
504343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return true;
504443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
504543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
504643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Is the object the prototype for this object?
5047c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (map_of_this->prototype() == obj) {
504843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return true;
504943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
505043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
505143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if the object is among the named properties.
505243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* key = SlowReverseLookup(obj);
5053ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!key->IsUndefined()) {
505443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return true;
505543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
505643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
505743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if the object is among the indexed properties.
50587b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  ElementsKind kind = GetElementsKind();
50597b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  switch (kind) {
5060af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    // Raw pixels and external arrays do not reference other
5061af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    // objects.
5062af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
5063af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_##TYPE##_ELEMENTS:                                           \
5064af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case TYPE##_ELEMENTS:                                                      \
5065af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      break;
5066af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
5067af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(TYPED_ARRAY_CASE)
5068af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef TYPED_ARRAY_CASE
5069af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
50707b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    case FAST_DOUBLE_ELEMENTS:
5071830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_DOUBLE_ELEMENTS:
50720b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
5073830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_SMI_ELEMENTS:
5074830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_SMI_ELEMENTS:
5075c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      break;
50767b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    case FAST_ELEMENTS:
5077830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_ELEMENTS:
50780b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    case DICTIONARY_ELEMENTS: {
50797b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      FixedArray* elements = FixedArray::cast(this->elements());
50807b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      if (ReferencesObjectFromElements(elements, kind, obj)) return true;
50810b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
508243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
5083486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    case SLOPPY_ARGUMENTS_ELEMENTS: {
50847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      FixedArray* parameter_map = FixedArray::cast(elements());
50857b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // Check the mapped parameters.
50867b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      int length = parameter_map->length();
50877b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      for (int i = 2; i < length; ++i) {
50887b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        Object* value = parameter_map->get(i);
50897b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        if (!value->IsTheHole() && value == obj) return true;
50907b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
50917b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // Check the arguments.
50927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
5093830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS :
5094830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org          FAST_HOLEY_ELEMENTS;
50957b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      if (ReferencesObjectFromElements(arguments, kind, obj)) return true;
50960b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
50977b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
509843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
509943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5100c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  // For functions check the context.
5101c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  if (IsJSFunction()) {
510243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Get the constructor function for arguments array.
5103f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    Map* arguments_map =
5104f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        heap->isolate()->context()->native_context()->sloppy_arguments_map();
510543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    JSFunction* arguments_function =
5106f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        JSFunction::cast(arguments_map->constructor());
510743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
510846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // Get the context and don't check if it is the native context.
510943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    JSFunction* f = JSFunction::cast(this);
511043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Context* context = f->context();
511146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    if (context->IsNativeContext()) {
511243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return false;
511343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
511443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
511543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Check the non-special context slots.
511643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (int i = Context::MIN_CONTEXT_SLOTS; i < context->length(); i++) {
511743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Only check JS objects.
511843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (context->get(i)->IsJSObject()) {
511943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        JSObject* ctxobj = JSObject::cast(context->get(i));
512043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        // If it is an arguments array check the content.
512143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (ctxobj->map()->constructor() == arguments_function) {
512243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          if (ctxobj->ReferencesObject(obj)) {
512343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            return true;
512443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          }
512543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        } else if (ctxobj == obj) {
512643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          return true;
512743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
512843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
512943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
513043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
51316d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    // Check the context extension (if any) if it can have references.
51326d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    if (context->has_extension() && !context->IsCatchContext()) {
5133f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      // With harmony scoping, a JSFunction may have a global context.
5134f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      // TODO(mvstanton): walk into the ScopeInfo.
5135f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      if (FLAG_harmony_scoping && context->IsGlobalContext()) {
5136f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        return false;
5137f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      }
5138f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
51396d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      return JSObject::cast(context->extension())->ReferencesObject(obj);
514043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
514143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
514243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
514343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // No references to object.
514443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return false;
514543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
514643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
514743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
51488496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.orgMaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
5149528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Isolate* isolate = object->GetIsolate();
5150057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
5151057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  if (!object->map()->is_extensible()) return object;
5152057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
5153528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (object->IsAccessCheckNeeded() &&
5154c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      !isolate->MayNamedAccess(
5155c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org          object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
5156c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
51578496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
5158528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return isolate->factory()->false_value();
51593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
51603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
5161528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (object->IsJSGlobalProxy()) {
516293720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    PrototypeIterator iter(isolate, object);
516393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    if (iter.IsAtEnd()) return object;
5164e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
516593720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    return PreventExtensions(
516693720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)));
5167d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  }
5168d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
516983e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  // It's not possible to seal objects with external array elements
5170895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  if (object->HasExternalArrayElements() ||
5171895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      object->HasFixedTypedArrayElements()) {
5172ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    THROW_NEW_ERROR(isolate,
5173ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                    NewTypeError("cant_prevent_ext_external_array_elements",
5174ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                 HandleVector(&object, 1)),
5175ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                    Object);
517683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  }
517783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org
517869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // If there are fast elements we normalize.
5179528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
5180e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->HasDictionaryElements() ||
5181528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org         object->HasDictionaryArgumentsElements());
5182528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
518369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // Make sure that we never go back to fast case.
51846db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  dictionary->set_requires_slow_elements();
518569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
518669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // Do a map transition, other objects with this map may still
518769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // be extensible.
5188a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
5189528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<Map> new_map = Map::Copy(handle(object->map()));
5190753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
51916db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  new_map->set_is_extensible(false);
519297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  JSObject::MigrateToMap(object, new_map);
5193e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->map()->is_extensible());
5194057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
519597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  if (object->map()->is_observed()) {
5196057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(),
5197057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org                        isolate->factory()->the_hole_value());
5198057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  }
5199528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  return object;
520069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org}
520169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
520269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
5203a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgtemplate<typename Dictionary>
5204a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgstatic void FreezeDictionary(Dictionary* dictionary) {
5205a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  int capacity = dictionary->Capacity();
5206a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  for (int i = 0; i < capacity; i++) {
5207a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    Object* k = dictionary->KeyAt(i);
520858a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org    if (dictionary->IsKey(k) &&
520958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org        !(k->IsSymbol() && Symbol::cast(k)->is_private())) {
5210a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      PropertyDetails details = dictionary->DetailsAt(i);
5211a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      int attrs = DONT_DELETE;
5212a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      // READ_ONLY is an invalid attribute for JS setters/getters.
5213255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      if (details.type() == CALLBACKS) {
5214255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        Object* v = dictionary->ValueAt(i);
5215255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value();
5216255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        if (!v->IsAccessorPair()) attrs |= READ_ONLY;
5217255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      } else {
5218a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org        attrs |= READ_ONLY;
5219a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      }
5220a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      details = details.CopyAddAttributes(
5221a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org          static_cast<PropertyAttributes>(attrs));
5222a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      dictionary->DetailsAtPut(i, details);
5223a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    }
5224a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
5225a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org}
5226a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5227a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5228255043f8054e713a64509c707cfabadd42344683machenbach@chromium.orgMaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) {
5229486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  // Freezing sloppy arguments should be handled elsewhere.
5230e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->HasSloppyArgumentsElements());
5231e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->map()->is_observed());
5232a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5233528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (object->map()->is_frozen()) return object;
5234a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5235528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Isolate* isolate = object->GetIsolate();
5236528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (object->IsAccessCheckNeeded() &&
5237c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      !isolate->MayNamedAccess(
5238c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org          object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
5239c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
5240255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
5241528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return isolate->factory()->false_value();
5242a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
5243a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5244528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (object->IsJSGlobalProxy()) {
524593720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    PrototypeIterator iter(isolate, object);
524693720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    if (iter.IsAtEnd()) return object;
5247e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
524893720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    return Freeze(Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)));
5249a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
5250a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5251a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  // It's not possible to freeze objects with external array elements
5252895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  if (object->HasExternalArrayElements() ||
5253895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      object->HasFixedTypedArrayElements()) {
5254ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    THROW_NEW_ERROR(isolate,
5255ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                    NewTypeError("cant_prevent_ext_external_array_elements",
5256ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                 HandleVector(&object, 1)),
5257ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                    Object);
5258a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
5259a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5260528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<SeededNumberDictionary> new_element_dictionary;
5261528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (!object->elements()->IsDictionary()) {
5262528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    int length = object->IsJSArray()
5263528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        ? Smi::cast(Handle<JSArray>::cast(object)->length())->value()
5264528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        : object->elements()->length();
5265a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (length > 0) {
5266a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      int capacity = 0;
5267a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      int used = 0;
5268528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      object->GetElementsCapacityAndUsage(&capacity, &used);
5269865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      new_element_dictionary = SeededNumberDictionary::New(isolate, used);
5270a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5271a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      // Move elements to a dictionary; avoid calling NormalizeElements to avoid
5272a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      // unnecessary transitions.
5273528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      new_element_dictionary = CopyFastElementsToDictionary(
5274528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          handle(object->elements()), length, new_element_dictionary);
5275a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    } else {
5276a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      // No existing elements, use a pre-allocated empty backing store
5277528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      new_element_dictionary =
5278528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          isolate->factory()->empty_slow_element_dictionary();
5279a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    }
5280a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
5281a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
52828f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<Map> old_map(object->map(), isolate);
52838f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int transition_index = old_map->SearchTransition(
52848f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      isolate->heap()->frozen_symbol());
52858f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  if (transition_index != TransitionArray::kNotFound) {
52868f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Handle<Map> transition_map(old_map->GetTransition(transition_index));
5287e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(transition_map->has_dictionary_elements());
5288e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(transition_map->is_frozen());
5289e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!transition_map->is_extensible());
529097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    JSObject::MigrateToMap(object, transition_map);
5291528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
5292a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    // Create a new descriptor array with fully-frozen properties
52939fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<Map> new_map = Map::CopyForFreeze(old_map);
529497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    JSObject::MigrateToMap(object, new_map);
5295a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  } else {
5296e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(old_map->is_dictionary_map() || !old_map->is_prototype_map());
5297a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    // Slow path: need to normalize properties for safety
5298528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
5299a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5300a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    // Create a new map, since other objects with this map may be extensible.
5301a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
5302528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<Map> new_map = Map::Copy(handle(object->map()));
5303a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    new_map->freeze();
5304a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    new_map->set_is_extensible(false);
5305a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    new_map->set_elements_kind(DICTIONARY_ELEMENTS);
530697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    JSObject::MigrateToMap(object, new_map);
5307a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5308a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    // Freeze dictionary-mode properties
5309528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    FreezeDictionary(object->property_dictionary());
5310a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
5311a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5312e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->map()->has_dictionary_elements());
5313528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (!new_element_dictionary.is_null()) {
5314528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    object->set_elements(*new_element_dictionary);
5315a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
5316a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5317528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) {
5318528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    SeededNumberDictionary* dictionary = object->element_dictionary();
5319a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    // Make sure we never go back to the fast case
5320a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    dictionary->set_requires_slow_elements();
5321a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    // Freeze all elements in the dictionary
5322a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    FreezeDictionary(dictionary);
5323a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
5324a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5325528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  return object;
5326a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org}
5327a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5328a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5329b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgvoid JSObject::SetObserved(Handle<JSObject> object) {
5330e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsJSGlobalProxy());
5331e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsJSGlobalObject());
5332b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  Isolate* isolate = object->GetIsolate();
5333b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  Handle<Map> new_map;
53348f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<Map> old_map(object->map(), isolate);
5335e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!old_map->is_observed());
53368f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int transition_index = old_map->SearchTransition(
53378f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      isolate->heap()->observed_symbol());
53388f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  if (transition_index != TransitionArray::kNotFound) {
53398f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    new_map = handle(old_map->GetTransition(transition_index), isolate);
5340e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(new_map->is_observed());
53415aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
53428f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    new_map = Map::CopyForObserved(old_map);
5343169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  } else {
53448f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    new_map = Map::Copy(old_map);
5345b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    new_map->set_is_observed();
5346169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
534797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  JSObject::MigrateToMap(object, new_map);
5348b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org}
5349169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
5350b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
535163a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.orgHandle<Object> JSObject::FastPropertyAt(Handle<JSObject> object,
535263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org                                        Representation representation,
5353e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                        FieldIndex index) {
535463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  Isolate* isolate = object->GetIsolate();
5355e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate);
535658a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org  return Object::WrapForRead(isolate, raw_value, representation);
535763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org}
535863a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
535963a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
536037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.orgtemplate<class ContextObject>
5361c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgclass JSObjectWalkVisitor {
5362c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org public:
536337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  JSObjectWalkVisitor(ContextObject* site_context, bool copying,
536437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                      JSObject::DeepCopyHints hints)
536537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    : site_context_(site_context),
536637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      copying_(copying),
536737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      hints_(hints) {}
5368c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
5369a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  MUST_USE_RESULT MaybeHandle<JSObject> StructureWalk(Handle<JSObject> object);
5370c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
537137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org protected:
5372a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  MUST_USE_RESULT inline MaybeHandle<JSObject> VisitElementOrProperty(
5373a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      Handle<JSObject> object,
5374a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      Handle<JSObject> value) {
5375b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    Handle<AllocationSite> current_site = site_context()->EnterNewScope();
5376a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    MaybeHandle<JSObject> copy_of_value = StructureWalk(value);
5377b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    site_context()->ExitScope(current_site, value);
5378b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    return copy_of_value;
5379b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  }
5380b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
538137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  inline ContextObject* site_context() { return site_context_; }
538237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  inline Isolate* isolate() { return site_context()->isolate(); }
5383b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
538437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  inline bool copying() const { return copying_; }
5385b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
538637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org private:
538737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  ContextObject* site_context_;
538837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  const bool copying_;
538937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  const JSObject::DeepCopyHints hints_;
539037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org};
5391b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
5392b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
539337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.orgtemplate <class ContextObject>
5394a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
539537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    Handle<JSObject> object) {
539637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  Isolate* isolate = this->isolate();
539737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  bool copying = this->copying();
5398f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  bool shallow = hints_ == JSObject::kObjectIsShallow;
5399c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
540037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  if (!shallow) {
540137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    StackLimitCheck check(isolate);
5402c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
540337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    if (check.HasOverflowed()) {
540437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      isolate->StackOverflow();
5405a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      return MaybeHandle<JSObject>();
540637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    }
5407e76560e31adc252866988b6fed3bba91a0e2855chpayer@chromium.org  }
54084f626d111ff758f7428aaa0cfe2153b477d4ed1ehpayer@chromium.org
5409528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (object->map()->is_deprecated()) {
5410c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org    JSObject::MigrateInstance(object);
54112f877ace3ac6432b1ce44abd553cd3ff97321680hpayer@chromium.org  }
5412528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
541337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  Handle<JSObject> copy;
541437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  if (copying) {
541537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    Handle<AllocationSite> site_to_pass;
5416c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org    if (site_context()->ShouldCreateMemento(object)) {
541737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      site_to_pass = site_context()->current();
541837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    }
54193484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    copy = isolate->factory()->CopyJSObjectWithAllocationSite(
54203484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org        object, site_to_pass);
542137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  } else {
542237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    copy = object;
542337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  }
542437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
5425e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(copying || copy.is_identical_to(object));
5426528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
542737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  ElementsKind kind = copy->GetElementsKind();
542837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  if (copying && IsFastSmiOrObjectElementsKind(kind) &&
542937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      FixedArray::cast(copy->elements())->map() ==
543037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        isolate->heap()->fixed_cow_array_map()) {
543137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    isolate->counters()->cow_arrays_created_runtime()->Increment();
543237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  }
5433f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
543437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  if (!shallow) {
543537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    HandleScope scope(isolate);
543637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
5437fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    // Deep copy own properties.
543837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    if (copy->HasFastProperties()) {
543937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors());
544037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      int limit = copy->map()->NumberOfOwnDescriptors();
544137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      for (int i = 0; i < limit; i++) {
544237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        PropertyDetails details = descriptors->GetDetails(i);
544337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        if (details.type() != FIELD) continue;
5444e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i);
544537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        Handle<Object> value(object->RawFastPropertyAt(index), isolate);
544637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        if (value->IsJSObject()) {
5447a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org          ASSIGN_RETURN_ON_EXCEPTION(
5448a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org              isolate, value,
5449a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org              VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
5450a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org              JSObject);
545137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        } else {
545237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org          Representation representation = details.representation();
5453e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org          value = Object::NewStorageFor(isolate, value, representation);
545437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        }
5455c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org        if (copying) {
545637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org          copy->FastPropertyAtPut(index, *value);
545737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        }
545837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      }
545937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    } else {
546037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      Handle<FixedArray> names =
5461fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org          isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties());
5462fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      copy->GetOwnPropertyNames(*names, 0);
546337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      for (int i = 0; i < names->length(); i++) {
5464e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(names->get(i)->IsString());
546537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        Handle<String> key_string(String::cast(names->get(i)));
5466eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org        Maybe<PropertyAttributes> maybe =
54671845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org            JSReceiver::GetOwnPropertyAttributes(copy, key_string);
5468e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(maybe.has_value);
5469eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org        PropertyAttributes attributes = maybe.value;
547037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        // Only deep copy fields from the object literal expression.
547137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        // In particular, don't try to copy the length attribute of
547237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        // an array.
547337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        if (attributes != NONE) continue;
54742ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        Handle<Object> value =
54752ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org            Object::GetProperty(copy, key_string).ToHandleChecked();
547637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        if (value->IsJSObject()) {
5477a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org          Handle<JSObject> result;
5478a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org          ASSIGN_RETURN_ON_EXCEPTION(
5479a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org              isolate, result,
5480a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org              VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
5481a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org              JSObject);
548237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org          if (copying) {
548337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org            // Creating object copy for literals. No strict mode needed.
54849bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org            JSObject::SetProperty(copy, key_string, result, SLOPPY).Assert();
548537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org          }
5486c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org        }
5487f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      }
5488f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    }
5489f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
5490fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    // Deep copy own elements.
549137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    // Pixel elements cannot be created using an object literal.
5492e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!copy->HasExternalArrayElements());
549337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    switch (kind) {
549437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      case FAST_SMI_ELEMENTS:
549537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      case FAST_ELEMENTS:
549637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      case FAST_HOLEY_SMI_ELEMENTS:
549737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      case FAST_HOLEY_ELEMENTS: {
549837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        Handle<FixedArray> elements(FixedArray::cast(copy->elements()));
549937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        if (elements->map() == isolate->heap()->fixed_cow_array_map()) {
5500f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org#ifdef DEBUG
550137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org          for (int i = 0; i < elements->length(); i++) {
5502e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org            DCHECK(!elements->get(i)->IsJSObject());
550337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org          }
5504f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org#endif
550537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        } else {
550637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org          for (int i = 0; i < elements->length(); i++) {
550737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org            Handle<Object> value(elements->get(i), isolate);
5508e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org            DCHECK(value->IsSmi() ||
550937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                   value->IsTheHole() ||
551037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                   (IsFastObjectElementsKind(copy->GetElementsKind())));
551137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org            if (value->IsJSObject()) {
5512a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org              Handle<JSObject> result;
5513a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org              ASSIGN_RETURN_ON_EXCEPTION(
5514a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org                  isolate, result,
5515a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org                  VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
5516a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org                  JSObject);
551737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org              if (copying) {
551837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                elements->set(i, *result);
551937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org              }
5520c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org            }
5521f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          }
5522f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        }
552337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        break;
5524f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      }
552537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      case DICTIONARY_ELEMENTS: {
552637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        Handle<SeededNumberDictionary> element_dictionary(
552737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org            copy->element_dictionary());
552837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        int capacity = element_dictionary->Capacity();
552937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        for (int i = 0; i < capacity; i++) {
553037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org          Object* k = element_dictionary->KeyAt(i);
553137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org          if (element_dictionary->IsKey(k)) {
553237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org            Handle<Object> value(element_dictionary->ValueAt(i), isolate);
553337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org            if (value->IsJSObject()) {
5534a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org              Handle<JSObject> result;
5535a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org              ASSIGN_RETURN_ON_EXCEPTION(
5536a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org                  isolate, result,
5537a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org                  VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
5538a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org                  JSObject);
553937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org              if (copying) {
554037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                element_dictionary->ValueAtPut(i, *result);
554137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org              }
5542c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org            }
5543f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          }
5544f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        }
554537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        break;
5546f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      }
5547486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      case SLOPPY_ARGUMENTS_ELEMENTS:
554837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        UNIMPLEMENTED();
554937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        break;
5550af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
5551af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
5552af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
5553af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      case EXTERNAL_##TYPE##_ELEMENTS:                                         \
5554af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      case TYPE##_ELEMENTS:                                                    \
5555af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
5556af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      TYPED_ARRAYS(TYPED_ARRAY_CASE)
5557af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef TYPED_ARRAY_CASE
5558af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
555937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      case FAST_DOUBLE_ELEMENTS:
556037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      case FAST_HOLEY_DOUBLE_ELEMENTS:
556137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        // No contained objects, nothing to do.
556237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        break;
5563f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    }
5564f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
556537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
5566f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return copy;
5567f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
5568f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
5569f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
5570a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMaybeHandle<JSObject> JSObject::DeepWalk(
557137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    Handle<JSObject> object,
557237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    AllocationSiteCreationContext* site_context) {
557337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  JSObjectWalkVisitor<AllocationSiteCreationContext> v(site_context, false,
557437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                                                       kNoHints);
5575a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  MaybeHandle<JSObject> result = v.StructureWalk(object);
5576a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  Handle<JSObject> for_assert;
5577e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!result.ToHandle(&for_assert) || for_assert.is_identical_to(object));
5578b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  return result;
5579b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org}
5580b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
5581b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
5582a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMaybeHandle<JSObject> JSObject::DeepCopy(
5583a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    Handle<JSObject> object,
5584a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    AllocationSiteUsageContext* site_context,
5585a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org    DeepCopyHints hints) {
558637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, true, hints);
5587a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  MaybeHandle<JSObject> copy = v.StructureWalk(object);
5588a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  Handle<JSObject> for_assert;
5589e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!copy.ToHandle(&for_assert) || !for_assert.is_identical_to(object));
5590c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  return copy;
5591c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org}
5592c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
5593c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
559443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Tests for the fast common case for property enumeration:
5595394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// - This object and all prototypes has an enum cache (which means that
5596394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com//   it is no proxy, has no interceptors and needs no access checks).
5597ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org// - This object has no elements.
5598ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org// - No prototype has enumerable properties/elements.
5599394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.combool JSReceiver::IsSimpleEnum() {
560093720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  for (PrototypeIterator iter(GetIsolate(), this,
560193720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org                              PrototypeIterator::START_AT_RECEIVER);
560293720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org       !iter.IsAtEnd(); iter.Advance()) {
560393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    if (!iter.GetCurrent()->IsJSObject()) return false;
560493720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    JSObject* curr = JSObject::cast(iter.GetCurrent());
5605355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    int enum_length = curr->map()->EnumLength();
5606af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    if (enum_length == kInvalidEnumCacheSentinel) return false;
5607486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    if (curr->IsAccessCheckNeeded()) return false;
5608e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!curr->HasNamedInterceptor());
5609e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!curr->HasIndexedInterceptor());
561043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (curr->NumberOfEnumElements() > 0) return false;
5611355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (curr != this && enum_length != 0) return false;
561243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
561343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return true;
561443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
561543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
561643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5617034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.orgstatic bool FilterKey(Object* key, PropertyAttributes filter) {
5618034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  if ((filter & SYMBOLIC) && key->IsSymbol()) {
5619034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    return true;
5620034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  }
5621034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
5622034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  if ((filter & PRIVATE_SYMBOL) &&
5623034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org      key->IsSymbol() && Symbol::cast(key)->is_private()) {
5624034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    return true;
5625034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  }
5626034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
5627034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  if ((filter & STRING) && !key->IsSymbol()) {
5628034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    return true;
5629034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  }
5630034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
5631034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  return false;
5632034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org}
5633034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
5634034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
563506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.orgint Map::NumberOfDescribedProperties(DescriptorFlag which,
563606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org                                     PropertyAttributes filter) {
563743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int result = 0;
5638defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  DescriptorArray* descs = instance_descriptors();
563906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  int limit = which == ALL_DESCRIPTORS
564006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org      ? descs->number_of_descriptors()
564106ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org      : NumberOfOwnDescriptors();
564206ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  for (int i = 0; i < limit; i++) {
5643750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if ((descs->GetDetails(i).attributes() & filter) == 0 &&
5644034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org        !FilterKey(descs->GetKey(i), filter)) {
5645750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      result++;
5646750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    }
564743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
564843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
564943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
565043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
565143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
565243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint Map::NextFreePropertyIndex() {
5653defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  int max_index = -1;
565406ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  int number_of_own_descriptors = NumberOfOwnDescriptors();
5655defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  DescriptorArray* descs = instance_descriptors();
565606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  for (int i = 0; i < number_of_own_descriptors; i++) {
5657defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    if (descs->GetType(i) == FIELD) {
5658defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      int current_index = descs->GetFieldIndex(i);
5659defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      if (current_index > max_index) max_index = current_index;
566043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
566143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
5662defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  return max_index + 1;
566343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
566443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
566543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
56669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgstatic bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
56679fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int len = array->length();
56689fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  for (int i = 0; i < len; i++) {
56699fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Object* e = array->get(i);
56709fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (!(e->IsString() || e->IsNumber())) return false;
56719fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
56729fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return true;
56739fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
56749fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
56759fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
56769fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgstatic Handle<FixedArray> ReduceFixedArrayTo(
56779fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<FixedArray> array, int length) {
5678e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(array->length() >= length);
56799fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (array->length() == length) return array;
56809fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
56819fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<FixedArray> new_array =
56829fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      array->GetIsolate()->factory()->NewFixedArray(length);
56839fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  for (int i = 0; i < length; ++i) new_array->set(i, array->get(i));
56849fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return new_array;
56859fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
56869fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
56879fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
56889fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgstatic Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object,
56899fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                              bool cache_result) {
56909fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
56919fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (object->HasFastProperties()) {
56929fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    int own_property_count = object->map()->EnumLength();
56939fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // If the enum length of the given map is set to kInvalidEnumCache, this
56949fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // means that the map itself has never used the present enum cache. The
56959fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // first step to using the cache is to set the enum length of the map by
56969fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // counting the number of own descriptors that are not DONT_ENUM or
56979fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // SYMBOLIC.
56989fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (own_property_count == kInvalidEnumCacheSentinel) {
56999fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      own_property_count = object->map()->NumberOfDescribedProperties(
57009fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          OWN_DESCRIPTORS, DONT_SHOW);
57019fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    } else {
5702e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(own_property_count == object->map()->NumberOfDescribedProperties(
57039fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          OWN_DESCRIPTORS, DONT_SHOW));
57049fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
57059fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
57069fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (object->map()->instance_descriptors()->HasEnumCache()) {
57079fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      DescriptorArray* desc = object->map()->instance_descriptors();
57089fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      Handle<FixedArray> keys(desc->GetEnumCache(), isolate);
57099fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
57109fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      // In case the number of properties required in the enum are actually
57119fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      // present, we can reuse the enum cache. Otherwise, this means that the
57129fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      // enum cache was generated for a previous (smaller) version of the
57139fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      // Descriptor Array. In that case we regenerate the enum cache.
57149fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      if (own_property_count <= keys->length()) {
57159fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        if (cache_result) object->map()->SetEnumLength(own_property_count);
57169fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        isolate->counters()->enum_cache_hits()->Increment();
57179fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        return ReduceFixedArrayTo(keys, own_property_count);
57189fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      }
57199fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
57209fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
57219fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<Map> map(object->map());
57229fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
57239fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (map->instance_descriptors()->IsEmpty()) {
57249fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      isolate->counters()->enum_cache_hits()->Increment();
57259fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      if (cache_result) map->SetEnumLength(0);
57269fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      return isolate->factory()->empty_fixed_array();
57279fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
57289fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
57299fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    isolate->counters()->enum_cache_misses()->Increment();
57309fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
57319fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<FixedArray> storage = isolate->factory()->NewFixedArray(
57329fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        own_property_count);
57339fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<FixedArray> indices = isolate->factory()->NewFixedArray(
57349fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        own_property_count);
57359fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
57369fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<DescriptorArray> descs =
57379fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        Handle<DescriptorArray>(object->map()->instance_descriptors(), isolate);
57389fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
57399fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    int size = map->NumberOfOwnDescriptors();
57409fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    int index = 0;
57419fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
57429fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    for (int i = 0; i < size; i++) {
57439fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      PropertyDetails details = descs->GetDetails(i);
57449fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      Object* key = descs->GetKey(i);
57459fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      if (!(details.IsDontEnum() || key->IsSymbol())) {
57469fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        storage->set(index, key);
57479fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        if (!indices.is_null()) {
57489fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          if (details.type() != FIELD) {
57499fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org            indices = Handle<FixedArray>();
57509fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          } else {
5751e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org            FieldIndex field_index = FieldIndex::ForDescriptor(*map, i);
5752e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org            int load_by_field_index = field_index.GetLoadByFieldIndex();
5753e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org            indices->set(index, Smi::FromInt(load_by_field_index));
57549fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          }
57559fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        }
57569fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        index++;
57579fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      }
57589fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
5759e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(index == storage->length());
57609fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
57619fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<FixedArray> bridge_storage =
57629fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        isolate->factory()->NewFixedArray(
57639fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org            DescriptorArray::kEnumCacheBridgeLength);
57649fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    DescriptorArray* desc = object->map()->instance_descriptors();
57659fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    desc->SetEnumCache(*bridge_storage,
57669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                       *storage,
57679fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                       indices.is_null() ? Object::cast(Smi::FromInt(0))
57689fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                         : Object::cast(*indices));
57699fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (cache_result) {
57709fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      object->map()->SetEnumLength(own_property_count);
57719fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
57729fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    return storage;
57739fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  } else {
57749fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<NameDictionary> dictionary(object->property_dictionary());
57759fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    int length = dictionary->NumberOfEnumElements();
57769fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (length == 0) {
57779fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
57789fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
57799fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length);
57809fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    dictionary->CopyEnumKeysTo(*storage);
57819fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    return storage;
57829fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
57839fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
57849fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
57859fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
57869fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgMaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
57879fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                            KeyCollectionType type) {
57889fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  USE(ContainsOnlyValidKeys);
57899fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
57909fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<FixedArray> content = isolate->factory()->empty_fixed_array();
5791f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  Handle<JSFunction> arguments_function(
5792f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      JSFunction::cast(isolate->sloppy_arguments_map()->constructor()));
57939fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
57949fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Only collect keys if access is permitted.
57959bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  for (PrototypeIterator iter(isolate, object,
57969bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                              PrototypeIterator::START_AT_RECEIVER);
57979bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org       !iter.IsAtEnd(); iter.Advance()) {
57989bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
57999bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org      Handle<JSProxy> proxy(JSProxy::cast(*PrototypeIterator::GetCurrent(iter)),
58009bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                            isolate);
58019fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      Handle<Object> args[] = { proxy };
58029fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      Handle<Object> names;
58039fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      ASSIGN_RETURN_ON_EXCEPTION(
58049fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          isolate, names,
58059fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          Execution::Call(isolate,
58069fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                          isolate->proxy_enumerate(),
58079fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                          object,
5808fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                          arraysize(args),
58099fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                          args),
58109fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          FixedArray);
58119fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      ASSIGN_RETURN_ON_EXCEPTION(
58129fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          isolate, content,
58133484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org          FixedArray::AddKeysFromArrayLike(
58143484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org              content, Handle<JSObject>::cast(names)),
58159fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          FixedArray);
58169fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      break;
58179fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
58189fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
58199bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    Handle<JSObject> current =
58209bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
58219fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
58229fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // Check access rights if required.
58239fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (current->IsAccessCheckNeeded() &&
58249fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        !isolate->MayNamedAccess(
58259fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org            current, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
58269fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      isolate->ReportFailedAccessCheck(current, v8::ACCESS_KEYS);
58279fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray);
58289fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      break;
58299fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
58309fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
58319fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // Compute the element keys.
58329fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<FixedArray> element_keys =
58339fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        isolate->factory()->NewFixedArray(current->NumberOfEnumElements());
58349fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    current->GetEnumElementKeys(*element_keys);
58359fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION(
58369fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        isolate, content,
58379fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        FixedArray::UnionOfKeys(content, element_keys),
58389fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        FixedArray);
5839e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(ContainsOnlyValidKeys(content));
58409fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
58419fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // Add the element keys from the interceptor.
58429fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (current->HasIndexedInterceptor()) {
58433484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      Handle<JSObject> result;
58449fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      if (JSObject::GetKeysForIndexedInterceptor(
58459fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org              current, object).ToHandle(&result)) {
58469fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        ASSIGN_RETURN_ON_EXCEPTION(
58479fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org            isolate, content,
58483484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org            FixedArray::AddKeysFromArrayLike(content, result),
58499fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org            FixedArray);
58509fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      }
5851e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(ContainsOnlyValidKeys(content));
58529fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
58539fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
58549fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // We can cache the computed property keys if access checks are
58559fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // not needed and no interceptors are involved.
58569fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    //
58579fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // We do not use the cache if the object has elements and
58589fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // therefore it does not make sense to cache the property names
58599fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // for arguments objects.  Arguments objects will always have
58609fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // elements.
58619fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // Wrapped strings have elements, but don't have an elements
58629fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // array or dictionary.  So the fast inline test for whether to
58639fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // use the cache says yes, so we should not create a cache.
58649fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    bool cache_enum_keys =
58659fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        ((current->map()->constructor() != *arguments_function) &&
58669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org         !current->IsJSValue() &&
58679fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org         !current->IsAccessCheckNeeded() &&
58689fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org         !current->HasNamedInterceptor() &&
58699fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org         !current->HasIndexedInterceptor());
58709fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // Compute the property keys and cache them if possible.
58719fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION(
58729fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        isolate, content,
58739fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        FixedArray::UnionOfKeys(
58749fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org            content, GetEnumPropertyKeys(current, cache_enum_keys)),
58759fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        FixedArray);
5876e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(ContainsOnlyValidKeys(content));
58779fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
58789fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // Add the property keys from the interceptor.
58799fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (current->HasNamedInterceptor()) {
58803484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      Handle<JSObject> result;
58819fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      if (JSObject::GetKeysForNamedInterceptor(
58829fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org              current, object).ToHandle(&result)) {
58839fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        ASSIGN_RETURN_ON_EXCEPTION(
58849fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org            isolate, content,
58853484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org            FixedArray::AddKeysFromArrayLike(content, result),
58869fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org            FixedArray);
58879fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      }
5888e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(ContainsOnlyValidKeys(content));
58899fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
58909fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
5891fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    // If we only want own properties we bail out after the first
58929fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // iteration.
5893fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    if (type == OWN_ONLY) break;
58949fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
58959fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return content;
58969fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
58979fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
58989fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
5899be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org// Try to update an accessor in an elements dictionary. Return true if the
5900be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org// update succeeded, and false otherwise.
5901be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgstatic bool UpdateGetterSetterInDictionary(
5902f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    SeededNumberDictionary* dictionary,
5903f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    uint32_t index,
590488aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org    Object* getter,
590588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org    Object* setter,
5906be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    PropertyAttributes attributes) {
59077b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  int entry = dictionary->FindEntry(index);
5908f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (entry != SeededNumberDictionary::kNotFound) {
59097b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    Object* result = dictionary->ValueAt(entry);
59107b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    PropertyDetails details = dictionary->DetailsAt(entry);
5911f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    if (details.type() == CALLBACKS && result->IsAccessorPair()) {
5912f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org      DCHECK(details.IsConfigurable());
5913394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      if (details.attributes() != attributes) {
5914f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org        dictionary->DetailsAtPut(
5915f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org            entry,
591657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org            PropertyDetails(attributes, CALLBACKS, index));
5917394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      }
591888aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org      AccessorPair::cast(result)->SetComponents(getter, setter);
5919be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      return true;
5920394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
59217b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
5922be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  return false;
59237b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org}
59247b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
59257b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
5926c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgvoid JSObject::DefineElementAccessor(Handle<JSObject> object,
5927c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org                                     uint32_t index,
5928c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org                                     Handle<Object> getter,
5929c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org                                     Handle<Object> setter,
5930975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org                                     PropertyAttributes attributes) {
5931c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  switch (object->GetElementsKind()) {
5932830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_SMI_ELEMENTS:
5933be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    case FAST_ELEMENTS:
5934be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    case FAST_DOUBLE_ELEMENTS:
5935830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_SMI_ELEMENTS:
5936830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_ELEMENTS:
5937830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_DOUBLE_ELEMENTS:
5938be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      break;
5939af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
5940af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
5941af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_##TYPE##_ELEMENTS:                                           \
5942af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case TYPE##_ELEMENTS:                                                      \
5943af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
5944af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(TYPED_ARRAY_CASE)
5945af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef TYPED_ARRAY_CASE
5946be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      // Ignore getters and setters on pixel and external array elements.
5947c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      return;
5948af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
5949be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    case DICTIONARY_ELEMENTS:
5950c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      if (UpdateGetterSetterInDictionary(object->element_dictionary(),
5951be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                                         index,
5952c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org                                         *getter,
5953c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org                                         *setter,
5954be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                                         attributes)) {
5955c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org        return;
59567b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
5957be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      break;
5958486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    case SLOPPY_ARGUMENTS_ELEMENTS: {
5959be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      // Ascertain whether we have read-only properties or an existing
5960be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      // getter/setter pair in an arguments elements dictionary backing
5961be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      // store.
5962c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      FixedArray* parameter_map = FixedArray::cast(object->elements());
5963be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      uint32_t length = parameter_map->length();
5964be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      Object* probe =
5965be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org          index < (length - 2) ? parameter_map->get(index + 2) : NULL;
5966be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      if (probe == NULL || probe->IsTheHole()) {
5967be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org        FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
5968be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org        if (arguments->IsDictionary()) {
5969be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org          SeededNumberDictionary* dictionary =
5970be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org              SeededNumberDictionary::cast(arguments);
5971be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org          if (UpdateGetterSetterInDictionary(dictionary,
5972be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                                             index,
5973c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org                                             *getter,
5974c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org                                             *setter,
5975be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                                             attributes)) {
5976c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org            return;
59770b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org          }
5978bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        }
5979bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      }
5980be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      break;
5981bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
5982be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  }
5983be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5984c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
5985c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  Handle<AccessorPair> accessors = isolate->factory()->NewAccessorPair();
5986c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  accessors->SetComponents(*getter, *setter);
5987be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
59888fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  SetElementCallback(object, index, accessors, attributes);
5989be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org}
5990be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5991be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5992e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgbool Map::DictionaryElementsInPrototypeChainOnly() {
5993e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  if (IsDictionaryElementsKind(elements_kind())) {
5994e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    return false;
5995e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  }
5996e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
59979bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) {
59989bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    if (iter.GetCurrent()->IsJSProxy()) {
5999e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      // Be conservative, don't walk into proxies.
6000e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      return true;
6001e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    }
6002e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
6003e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    if (IsDictionaryElementsKind(
60049bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org            JSObject::cast(iter.GetCurrent())->map()->elements_kind())) {
6005e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      return true;
6006e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    }
6007e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  }
6008e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
6009e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  return false;
6010e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org}
6011e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
6012e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
60138fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.orgvoid JSObject::SetElementCallback(Handle<JSObject> object,
60148fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org                                  uint32_t index,
60158fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org                                  Handle<Object> structure,
60168fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org                                  PropertyAttributes attributes) {
60178fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  Heap* heap = object->GetHeap();
601857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0);
60199155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
60209155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // Normalize elements to make this operation simple.
6021e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  bool had_dictionary_elements = object->HasDictionaryElements();
60228fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
6023e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->HasDictionaryElements() ||
60248fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org         object->HasDictionaryArgumentsElements());
60259155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // Update the dictionary with the new CALLBACKS property.
60268fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  dictionary = SeededNumberDictionary::Set(dictionary, index, structure,
60278fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org                                           details);
60287b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  dictionary->set_requires_slow_elements();
60298fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org
60307b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Update the dictionary backing store on the object.
6031486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (object->elements()->map() == heap->sloppy_arguments_elements_map()) {
60327b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // Also delete any parameter alias.
60337b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    //
60347b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // TODO(kmillikin): when deleting the last parameter alias we could
60357b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // switch to a direct backing store without the parameter map.  This
60367b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // would allow GC of the context.
60378fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    FixedArray* parameter_map = FixedArray::cast(object->elements());
6038be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    if (index < static_cast<uint32_t>(parameter_map->length()) - 2) {
60398fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org      parameter_map->set(index + 2, heap->the_hole_value());
60407b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
60418fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    parameter_map->set(1, *dictionary);
60427b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  } else {
60438fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    object->set_elements(*dictionary);
6044e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
6045e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    if (!had_dictionary_elements) {
6046e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      // KeyedStoreICs (at least the non-generic ones) need a reset.
6047e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      heap->ClearAllICsByKind(Code::KEYED_STORE_IC);
6048e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    }
6049303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
605043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
605143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
605243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
60538fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.orgvoid JSObject::SetPropertyCallback(Handle<JSObject> object,
60548fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org                                   Handle<Name> name,
60558fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org                                   Handle<Object> structure,
60568fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org                                   PropertyAttributes attributes) {
6057e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  PropertyNormalizationMode mode = object->map()->is_prototype_map()
6058e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                                       ? KEEP_INOBJECT_PROPERTIES
6059e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                                       : CLEAR_INOBJECT_PROPERTIES;
60609155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // Normalize object to make this operation simple.
6061e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  NormalizeProperties(object, mode, 0);
60629155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
60639155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // For the global object allocate a new map to invalidate the global inline
60649155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // caches which have a global property cell reference directly in the code.
60658fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  if (object->IsGlobalObject()) {
60668fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
6067e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(new_map->is_dictionary_map());
606808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    JSObject::MigrateToMap(object, new_map);
6069753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
6070a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // When running crankshaft, changing the map is not enough. We
6071a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // need to deoptimize all functions that rely on this global
6072a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // object.
60738fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    Deoptimizer::DeoptimizeGlobalObject(*object);
60749155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  }
60759155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
60769155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // Update the dictionary with the new CALLBACKS property.
607757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0);
60788fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  SetNormalizedProperty(object, name, structure, details);
6079e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
6080e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  ReoptimizeIfPrototype(object);
60819155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org}
60829155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
608388aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org
6084eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgMaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
6085eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                             Handle<Name> name,
6086eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                             Handle<Object> getter,
6087eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                             Handle<Object> setter,
6088eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                             PropertyAttributes attributes) {
6089c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
60905a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  // Check access rights if needed.
6091c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  if (object->IsAccessCheckNeeded() &&
6092c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
6093c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
6094eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
6095eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    return isolate->factory()->undefined_value();
60965a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
60975a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
6098c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  if (object->IsJSGlobalProxy()) {
609993720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    PrototypeIterator iter(isolate, object);
6100eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    if (iter.IsAtEnd()) return isolate->factory()->undefined_value();
6101e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
610293720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    DefineAccessor(Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
610393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org                   name, getter, setter, attributes);
6104eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    return isolate->factory()->undefined_value();
61055a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
61065a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
6107be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // Make sure that the top context does not change when doing callbacks or
6108be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // interceptor calls.
6109fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  AssertNoContextChange ncc(isolate);
6110be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6111be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // Try to flatten before operating on the string.
61129e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
6113be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
6114be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  uint32_t index = 0;
6115e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  bool is_element = name->AsArrayIndex(&index);
6116e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
6117fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  Handle<Object> old_value = isolate->factory()->the_hole_value();
611897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  bool is_observed = object->map()->is_observed() &&
6119690083842e7c67a362017dae50909d4bb0b2a9c2mstarzinger@chromium.org                     *name != isolate->heap()->hidden_string();
6120e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  bool preexists = false;
612183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  if (is_observed) {
6122e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    if (is_element) {
6123eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      Maybe<bool> maybe = HasOwnElement(object, index);
61242b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org      // Workaround for a GCC 4.4.3 bug which leads to "‘preexists’ may be used
61252b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org      // uninitialized in this function".
61262b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org      if (!maybe.has_value) {
6127e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(false);
61282b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org        return isolate->factory()->undefined_value();
61292b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org      }
6130eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      preexists = maybe.value;
6131fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      if (preexists && GetOwnElementAccessorPair(object, index).is_null()) {
61322ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        old_value =
61332ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org            Object::GetElement(isolate, object, index).ToHandleChecked();
6134e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      }
6135e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    } else {
61366474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      LookupIterator it(object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
61375e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      CHECK(GetPropertyAttributes(&it).has_value);
61385e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      preexists = it.IsFound();
61391af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      if (preexists && (it.state() == LookupIterator::DATA ||
61405e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                        it.GetAccessors()->IsAccessorInfo())) {
61415e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        old_value = GetProperty(&it).ToHandleChecked();
6142a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      }
6143e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
6144e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
6145e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
6146c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  if (is_element) {
6147975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    DefineElementAccessor(object, index, getter, setter, attributes);
6148c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  } else {
61497dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    DCHECK(getter->IsSpecFunction() || getter->IsUndefined() ||
61507dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org           getter->IsNull());
61517dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    DCHECK(setter->IsSpecFunction() || setter->IsUndefined() ||
61527dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org           setter->IsNull());
61537dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    // At least one of the accessors needs to be a new value.
61547dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    DCHECK(!getter->IsNull() || !setter->IsNull());
61559aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org    LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
61566313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org    if (it.state() == LookupIterator::ACCESS_CHECK) {
61576313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      // We already did an access check before. We do have access.
61586313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      it.Next();
61596313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org    }
61607dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    if (!getter->IsNull()) {
61617dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      it.TransitionToAccessorProperty(ACCESSOR_GETTER, getter, attributes);
61627dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    }
61637dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    if (!setter->IsNull()) {
61647dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      it.TransitionToAccessorProperty(ACCESSOR_SETTER, setter, attributes);
61657dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    }
6166c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  }
6167e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
616883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  if (is_observed) {
6169e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    const char* type = preexists ? "reconfigure" : "add";
6170c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    EnqueueChangeRecord(object, type, name, old_value);
6171e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
6172eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org
6173eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  return isolate->factory()->undefined_value();
617443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
617543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
617643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
61778496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.orgMaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
61788496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                          Handle<AccessorInfo> info) {
61798fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  Isolate* isolate = object->GetIsolate();
61808fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  Factory* factory = isolate->factory();
61818fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  Handle<Name> name(Name::cast(info->name()));
61828fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org
61839155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // Check access rights if needed.
61848fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  if (object->IsAccessCheckNeeded() &&
6185c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
6186c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
61878496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
61888fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    return factory->undefined_value();
61899155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  }
61909155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
61918fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  if (object->IsJSGlobalProxy()) {
619293720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    PrototypeIterator iter(isolate, object);
619393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    if (iter.IsAtEnd()) return object;
6194e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
619593720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    return SetAccessor(
619693720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), info);
61979155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  }
61989155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
61999155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // Make sure that the top context does not change when doing callbacks or
62009155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // interceptor calls.
6201fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  AssertNoContextChange ncc(isolate);
62029155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
62039155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // Try to flatten before operating on the string.
62049e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
62059155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
62069155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  uint32_t index = 0;
62079155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  bool is_element = name->AsArrayIndex(&index);
62089155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
62099155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  if (is_element) {
62108fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    if (object->IsJSArray()) return factory->undefined_value();
62119155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
62129155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    // Accessors overwrite previous callbacks (cf. with getters/setters).
62138fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    switch (object->GetElementsKind()) {
6214830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_SMI_ELEMENTS:
62159155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org      case FAST_ELEMENTS:
62169fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org      case FAST_DOUBLE_ELEMENTS:
6217830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_HOLEY_SMI_ELEMENTS:
6218830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_HOLEY_ELEMENTS:
6219830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_HOLEY_DOUBLE_ELEMENTS:
62209155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org        break;
6221af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
6222af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
6223af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      case EXTERNAL_##TYPE##_ELEMENTS:                                         \
6224af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      case TYPE##_ELEMENTS:                                                    \
6225af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
6226af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      TYPED_ARRAYS(TYPED_ARRAY_CASE)
6227af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef TYPED_ARRAY_CASE
62289155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org        // Ignore getters and setters on pixel and external array
62299155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org        // elements.
62308fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org        return factory->undefined_value();
6231af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
62329155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org      case DICTIONARY_ELEMENTS:
62339155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org        break;
6234486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      case SLOPPY_ARGUMENTS_ELEMENTS:
62357b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        UNIMPLEMENTED();
62369155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org        break;
62379155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    }
62389155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
62398fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    SetElementCallback(object, index, info, info->property_attributes());
62409155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  } else {
62419155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    // Lookup the name.
62426474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    LookupIterator it(object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
62435e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    CHECK(GetPropertyAttributes(&it).has_value);
62449155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    // ES5 forbids turning a property into an accessor if it's not
62455e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    // configurable. See 8.6.1 (Table 5).
62465e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    if (it.IsFound() && (it.IsReadOnly() || !it.IsConfigurable())) {
62478fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org      return factory->undefined_value();
62489155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    }
6249753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
62508fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    SetPropertyCallback(object, name, info, info->property_attributes());
62519155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  }
62529155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
62538fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  return object;
62549155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org}
62559155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
62569155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
62578496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.orgMaybeHandle<Object> JSObject::GetAccessor(Handle<JSObject> object,
62588496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                          Handle<Name> name,
62598496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                          AccessorComponent component) {
6260fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  Isolate* isolate = object->GetIsolate();
6261ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
626243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make sure that the top context does not change when doing callbacks or
626343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // interceptor calls.
6264fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  AssertNoContextChange ncc(isolate);
626543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
626643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make the lookup and include prototypes.
62671af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  uint32_t index = 0;
6268bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (name->AsArrayIndex(&index)) {
626993720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    for (PrototypeIterator iter(isolate, object,
627093720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org                                PrototypeIterator::START_AT_RECEIVER);
627193720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org         !iter.IsAtEnd(); iter.Advance()) {
62725e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      Handle<Object> current = PrototypeIterator::GetCurrent(iter);
62735e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      // Check access rights if needed.
62745e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if (current->IsAccessCheckNeeded() &&
62755e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          !isolate->MayNamedAccess(Handle<JSObject>::cast(current), name,
62765e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                                   v8::ACCESS_HAS)) {
62775e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(current),
62785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                                         v8::ACCESS_HAS);
62795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
62805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        return isolate->factory()->undefined_value();
62815e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
62825e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
62835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if (current->IsJSObject() &&
62845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          Handle<JSObject>::cast(current)->HasDictionaryElements()) {
62855e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        JSObject* js_object = JSObject::cast(*current);
6286f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        SeededNumberDictionary* dictionary = js_object->element_dictionary();
628786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        int entry = dictionary->FindEntry(index);
6288f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        if (entry != SeededNumberDictionary::kNotFound) {
6289bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          Object* element = dictionary->ValueAt(entry);
62909a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org          if (dictionary->DetailsAt(entry).type() == CALLBACKS &&
62919a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org              element->IsAccessorPair()) {
6292fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org            return handle(AccessorPair::cast(element)->GetComponent(component),
6293fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                          isolate);
6294bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
6295bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        }
6296bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      }
6297bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    }
6298bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  } else {
62995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    LookupIterator it(object, name,
63006474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                      LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
63015e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    for (; it.IsFound(); it.Next()) {
63025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      switch (it.state()) {
63035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case LookupIterator::INTERCEPTOR:
6304a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        case LookupIterator::NOT_FOUND:
6305a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        case LookupIterator::TRANSITION:
63065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          UNREACHABLE();
63075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
63085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case LookupIterator::ACCESS_CHECK:
63095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (it.HasAccess(v8::ACCESS_HAS)) continue;
63105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>(),
63115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                                           v8::ACCESS_HAS);
63125e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
63135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          return isolate->factory()->undefined_value();
63145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
63155e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case LookupIterator::JSPROXY:
63165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          return isolate->factory()->undefined_value();
63175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
63181af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        case LookupIterator::DATA:
63191af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          continue;
63201af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        case LookupIterator::ACCESSOR: {
63211af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          Handle<Object> maybe_pair = it.GetAccessors();
63221af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org          if (maybe_pair->IsAccessorPair()) {
63231af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org            return handle(
63241af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org                AccessorPair::cast(*maybe_pair)->GetComponent(component),
63251af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org                isolate);
6326bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org          }
63271af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        }
632843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
632943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
633043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
6331fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  return isolate->factory()->undefined_value();
633243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
633343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
633443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
633543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenObject* JSObject::SlowReverseLookup(Object* value) {
633643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (HasFastProperties()) {
633706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    int number_of_own_descriptors = map()->NumberOfOwnDescriptors();
6338defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    DescriptorArray* descs = map()->instance_descriptors();
633906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    for (int i = 0; i < number_of_own_descriptors; i++) {
6340defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      if (descs->GetType(i) == FIELD) {
6341e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        Object* property =
6342e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org            RawFastPropertyAt(FieldIndex::ForDescriptor(map(), i));
6343bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org        if (descs->GetDetails(i).representation().IsDouble()) {
6344e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(property->IsMutableHeapNumber());
634557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          if (value->IsNumber() && property->Number() == value->Number()) {
634657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org            return descs->GetKey(i);
634757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          }
634857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        } else if (property == value) {
6349defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org          return descs->GetKey(i);
635043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
6351fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      } else if (descs->GetType(i) == CONSTANT) {
6352fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        if (descs->GetConstant(i) == value) {
6353defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org          return descs->GetKey(i);
635443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
635543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
635643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
6357c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return GetHeap()->undefined_value();
635843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
635943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return property_dictionary()->SlowReverseLookup(value);
636043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
636143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
636243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
636343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
63642ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgHandle<Map> Map::RawCopy(Handle<Map> map, int instance_size) {
63652ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Map> result = map->GetIsolate()->factory()->NewMap(
63662ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      map->instance_type(), instance_size);
63672ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  result->set_prototype(map->prototype());
63682ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  result->set_constructor(map->constructor());
63692ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  result->set_bit_field(map->bit_field());
63702ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  result->set_bit_field2(map->bit_field2());
63712ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int new_bit_field3 = map->bit_field3();
637206ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true);
637306ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0);
6374af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  new_bit_field3 = EnumLengthBits::update(new_bit_field3,
6375af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org                                          kInvalidEnumCacheSentinel);
637657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  new_bit_field3 = Deprecated::update(new_bit_field3, false);
63772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (!map->is_dictionary_map()) {
637857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    new_bit_field3 = IsUnstable::update(new_bit_field3, false);
637957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  }
6380011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  new_bit_field3 = ConstructionCount::update(new_bit_field3,
6381011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org                                             JSFunction::kNoSlackTracking);
638206ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  result->set_bit_field3(new_bit_field3);
638343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
638443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
638543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
638643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6387c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.orgHandle<Map> Map::Normalize(Handle<Map> fast_map,
6388c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org                           PropertyNormalizationMode mode) {
6389e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!fast_map->is_dictionary_map());
6390c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
6391c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  Isolate* isolate = fast_map->GetIsolate();
639231c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  Handle<Object> maybe_cache(isolate->native_context()->normalized_map_cache(),
639331c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org                             isolate);
639431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  bool use_cache = !maybe_cache->IsUndefined();
639531c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  Handle<NormalizedMapCache> cache;
639631c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  if (use_cache) cache = Handle<NormalizedMapCache>::cast(maybe_cache);
6397c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
6398c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  Handle<Map> new_map;
639931c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  if (use_cache && cache->Get(fast_map, mode).ToHandle(&new_map)) {
6400c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org#ifdef VERIFY_HEAP
640131c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    if (FLAG_verify_heap) new_map->DictionaryMapVerify();
6402c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org#endif
6403e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org#ifdef ENABLE_SLOW_DCHECKS
6404c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    if (FLAG_enable_slow_asserts) {
6405c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org      // The cached map should match newly created normalized map bit-by-bit,
6406c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org      // except for the code cache, which can contain some ics which can be
6407c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org      // applied to the shared map.
640831c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      Handle<Map> fresh = Map::CopyNormalized(fast_map, mode);
6409c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
6410e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(memcmp(fresh->address(),
6411c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org                    new_map->address(),
6412c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org                    Map::kCodeCacheOffset) == 0);
6413c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org      STATIC_ASSERT(Map::kDependentCodeOffset ==
6414c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org                    Map::kCodeCacheOffset + kPointerSize);
6415c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org      int offset = Map::kDependentCodeOffset + kPointerSize;
6416e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(memcmp(fresh->address() + offset,
6417c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org                    new_map->address() + offset,
6418c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org                    Map::kSize - offset) == 0);
6419c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    }
6420c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org#endif
6421c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  } else {
642231c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    new_map = Map::CopyNormalized(fast_map, mode);
642331c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    if (use_cache) {
642431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      cache->Set(fast_map, new_map);
642531c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      isolate->counters()->normalized_maps()->Increment();
642631c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    }
6427c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  }
6428c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  fast_map->NotifyLeafMapLayoutChange();
6429c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  return new_map;
6430c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org}
6431c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
6432c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org
6433c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgHandle<Map> Map::CopyNormalized(Handle<Map> map,
643431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org                                PropertyNormalizationMode mode) {
6435c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  int new_instance_size = map->instance_size();
643665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  if (mode == CLEAR_INOBJECT_PROPERTIES) {
6437c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    new_instance_size -= map->inobject_properties() * kPointerSize;
643865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  }
643965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
6440c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  Handle<Map> result = RawCopy(map, new_instance_size);
644165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
644265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  if (mode != CLEAR_INOBJECT_PROPERTIES) {
6443c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    result->set_inobject_properties(map->inobject_properties());
644465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  }
644565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
644688767247437a4504f433cc5abea22a473e5ed982erik.corry@gmail.com  result->set_dictionary_map(true);
6447594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  result->set_migration_target(false);
64484a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
6449c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
645031c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  if (FLAG_verify_heap) result->DictionaryMapVerify();
645165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#endif
645265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
645365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  return result;
645465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}
645565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
645665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
6457ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgHandle<Map> Map::CopyDropDescriptors(Handle<Map> map) {
64582ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Map> result = RawCopy(map, map->instance_size());
6459657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
6460657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  // Please note instance_type and instance_size are set when allocated.
64612ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  result->set_inobject_properties(map->inobject_properties());
64622ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  result->set_unused_property_fields(map->unused_property_fields());
6463657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
64642ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  result->set_pre_allocated_property_fields(
64652ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      map->pre_allocated_property_fields());
64662ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  result->ClearCodeCache(map->GetHeap());
64672ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  map->NotifyLeafMapLayoutChange();
6468657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return result;
6469657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
6470657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
6471657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
64725b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgHandle<Map> Map::ShareDescriptor(Handle<Map> map,
64735b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                 Handle<DescriptorArray> descriptors,
64745b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                 Descriptor* descriptor) {
647506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  // Sanity check. This path is only to be taken if the map owns its descriptor
647606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  // array, implying that its NumberOfOwnDescriptors equals the number of
647706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  // descriptors in the descriptor array.
6478e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(map->NumberOfOwnDescriptors() ==
64795b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org         map->instance_descriptors()->number_of_descriptors());
648006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
6481c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  Handle<Map> result = CopyDropDescriptors(map);
64825b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Name> name = descriptor->GetKey();
648306ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
6484202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  // Ensure there's space for the new descriptor in the shared descriptor array.
6485202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  if (descriptors->NumberOfSlackDescriptors() == 0) {
64865b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    int old_size = descriptors->number_of_descriptors();
6487202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    if (old_size == 0) {
64882ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1);
6489202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    } else {
6490c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2);
6491202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      descriptors = handle(map->instance_descriptors());
649233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    }
6493202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  }
649433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
6495e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  {
6496e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DisallowHeapAllocation no_gc;
6497e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    descriptors->Append(descriptor);
6498e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    result->InitializeDescriptors(*descriptors);
6499e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  }
65005b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org
6501e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
6502e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  ConnectTransition(map, result, name, SIMPLE_TRANSITION);
650333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
6504e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  return result;
6505e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
650606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
650789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
6508e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid Map::ConnectTransition(Handle<Map> parent, Handle<Map> child,
6509e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                            Handle<Name> name, SimpleTransitionFlag flag) {
6510e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  parent->set_owns_descriptors(false);
6511e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  if (parent->is_prototype_map()) {
6512e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(child->is_prototype_map());
6513e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  } else {
6514e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    Handle<TransitionArray> transitions =
6515e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        TransitionArray::CopyInsert(parent, name, child, flag);
6516e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    parent->set_transitions(*transitions);
6517e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    child->SetBackPointer(*parent);
6518e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  }
651906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org}
652006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
652106ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
6522528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgHandle<Map> Map::CopyReplaceDescriptors(Handle<Map> map,
6523528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                        Handle<DescriptorArray> descriptors,
6524528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                        TransitionFlag flag,
65259fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                        MaybeHandle<Name> maybe_name,
65265b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                        SimpleTransitionFlag simple_flag) {
6527e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(descriptors->IsSortedNoDuplicates());
652806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
65295b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Map> result = CopyDropDescriptors(map);
65305b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  result->InitializeDescriptors(*descriptors);
6531753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
6532e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  if (!map->is_prototype_map()) {
6533e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) {
6534e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      Handle<Name> name;
6535e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      CHECK(maybe_name.ToHandle(&name));
6536e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      ConnectTransition(map, result, name, simple_flag);
6537e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    } else {
6538e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      int length = descriptors->number_of_descriptors();
6539e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      for (int i = 0; i < length; i++) {
6540e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        descriptors->SetRepresentation(i, Representation::Tagged());
6541e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        if (descriptors->GetDetails(i).type() == FIELD) {
6542e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          descriptors->SetValue(i, HeapType::Any());
6543e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        }
6544e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      }
6545e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    }
6546753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  }
6547753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
6548657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return result;
6549657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
6550657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
6551657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
6552c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org// Since this method is used to rewrite an existing transition tree, it can
6553c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org// always insert transitions without checking.
6554528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgHandle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
6555528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                        int new_descriptor,
6556528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                        Handle<DescriptorArray> descriptors) {
6557e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(descriptors->IsSortedNoDuplicates());
6558f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
6559c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  Handle<Map> result = CopyDropDescriptors(map);
6560f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
6561c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  result->InitializeDescriptors(*descriptors);
6562f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  result->SetNumberOfOwnDescriptors(new_descriptor + 1);
6563f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
6564c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  int unused_property_fields = map->unused_property_fields();
6565f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  if (descriptors->GetDetails(new_descriptor).type() == FIELD) {
6566c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    unused_property_fields = map->unused_property_fields() - 1;
6567f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (unused_property_fields < 0) {
6568f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      unused_property_fields += JSObject::kFieldsAdded;
6569f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    }
6570f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
6571f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
6572f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  result->set_unused_property_fields(unused_property_fields);
6573f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
6574c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
6575e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  ConnectTransition(map, result, name, SIMPLE_TRANSITION);
6576f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
6577f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  return result;
6578f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
6579f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
6580f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
65815b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgHandle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
65825b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                    TransitionFlag flag) {
6583753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  if (flag == INSERT_TRANSITION) {
6584e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!map->HasElementsTransition() ||
65855b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org        ((map->elements_transition_map()->elements_kind() ==
65865b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org          DICTIONARY_ELEMENTS ||
6587753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org          IsExternalArrayElementsKind(
65885b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org              map->elements_transition_map()->elements_kind())) &&
6589753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org         (kind == DICTIONARY_ELEMENTS ||
6590753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org          IsExternalArrayElementsKind(kind))));
6591e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!IsFastElementsKind(kind) ||
65925b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org           IsMoreGeneralElementsKindTransition(map->elements_kind(), kind));
6593e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(kind != map->elements_kind());
659406ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  }
659506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
659689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  bool insert_transition =
65975b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      flag == INSERT_TRANSITION && !map->HasElementsTransition();
659889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
65995b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  if (insert_transition && map->owns_descriptors()) {
660006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    // In case the map owned its own descriptors, share the descriptors and
660106ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    // transfer ownership to the new map.
6602c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    Handle<Map> new_map = CopyDropDescriptors(map);
660306ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
6604e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    ConnectElementsTransition(map, new_map);
660506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
660606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    new_map->set_elements_kind(kind);
66075b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    new_map->InitializeDescriptors(map->instance_descriptors());
660806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    return new_map;
660906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  }
661006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
661106ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  // In case the map did not own its own descriptors, a split is forced by
661206ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  // copying the map; creating a new descriptor array cell.
661306ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  // Create a new free-floating map only if we are not allowed to store it.
6614c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  Handle<Map> new_map = Copy(map);
661589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
661606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  new_map->set_elements_kind(kind);
661756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org
661889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  if (insert_transition) {
6619e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    ConnectElementsTransition(map, new_map);
6620753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  }
6621753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
6622753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  return new_map;
6623753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org}
6624753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
6625753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
6626b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgHandle<Map> Map::CopyForObserved(Handle<Map> map) {
6627e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!map->is_observed());
6628b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
6629db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  Isolate* isolate = map->GetIsolate();
6630169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
6631169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // In case the map owned its own descriptors, share the descriptors and
6632169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  // transfer ownership to the new map.
6633db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  Handle<Map> new_map;
6634db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  if (map->owns_descriptors()) {
6635c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    new_map = CopyDropDescriptors(map);
6636169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  } else {
6637e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!map->is_prototype_map());
6638c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    new_map = Copy(map);
6639169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
6640169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
6641b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  new_map->set_is_observed();
6642db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  if (map->owns_descriptors()) {
6643db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org    new_map->InitializeDescriptors(map->instance_descriptors());
6644169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
6645169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
6646e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Handle<Name> name = isolate->factory()->observed_symbol();
6647e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  ConnectTransition(map, new_map, name, FULL_TRANSITION);
6648e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
6649169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  return new_map;
6650169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
6651169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
6652169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
6653c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgHandle<Map> Map::Copy(Handle<Map> map) {
66545b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<DescriptorArray> descriptors(map->instance_descriptors());
66555b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  int number_of_own_descriptors = map->NumberOfOwnDescriptors();
66565b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<DescriptorArray> new_descriptors =
66575b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors);
66589fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return CopyReplaceDescriptors(
66599fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      map, new_descriptors, OMIT_TRANSITION, MaybeHandle<Name>());
6660657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
6661657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
6662657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
6663a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgHandle<Map> Map::Create(Isolate* isolate, int inobject_properties) {
6664a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Handle<Map> copy = Copy(handle(isolate->object_function()->initial_map()));
66654edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
6666a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  // Check that we do not overflow the instance size when adding the extra
6667a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  // inobject properties. If the instance size overflows, we allocate as many
6668a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  // properties as we can as inobject properties.
6669a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  int max_extra_properties =
6670a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      (JSObject::kMaxInstanceSize - JSObject::kHeaderSize) >> kPointerSizeLog2;
66714edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
6672a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  if (inobject_properties > max_extra_properties) {
6673a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    inobject_properties = max_extra_properties;
66744edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  }
66754edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
6676a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  int new_instance_size =
6677a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      JSObject::kHeaderSize + kPointerSize * inobject_properties;
6678a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
66794edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  // Adjust the map with the extra inobject properties.
66804edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  copy->set_inobject_properties(inobject_properties);
66814edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  copy->set_unused_property_fields(inobject_properties);
6682a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  copy->set_instance_size(new_instance_size);
66834edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy));
66844edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  return copy;
66854edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org}
66864edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
66874edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
66889fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgHandle<Map> Map::CopyForFreeze(Handle<Map> map) {
66899fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int num_descriptors = map->NumberOfOwnDescriptors();
66909fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Isolate* isolate = map->GetIsolate();
66919fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes(
66929fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN);
66933c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Handle<Map> new_map = CopyReplaceDescriptors(
66949fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      map, new_desc, INSERT_TRANSITION, isolate->factory()->frozen_symbol());
66959fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  new_map->freeze();
66969fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  new_map->set_is_extensible(false);
66979fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  new_map->set_elements_kind(DICTIONARY_ELEMENTS);
66989fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return new_map;
66999fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
67009fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
67019fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
6702474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgbool DescriptorArray::CanHoldValue(int descriptor, Object* value) {
6703474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  PropertyDetails details = GetDetails(descriptor);
6704474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  switch (details.type()) {
6705474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    case FIELD:
6706474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      return value->FitsRepresentation(details.representation()) &&
6707474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org             GetFieldType(descriptor)->NowContains(value);
6708474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6709474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    case CONSTANT:
6710e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(GetConstant(descriptor) != value ||
6711474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org             value->FitsRepresentation(details.representation()));
6712474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      return GetConstant(descriptor) == value;
6713474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6714474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    case CALLBACKS:
6715474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      return false;
6716474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6717474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    case NORMAL:
6718fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      UNREACHABLE();
6719474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      break;
6720474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  }
6721474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6722474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  UNREACHABLE();
6723474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  return false;
6724474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org}
6725474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6726474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6727474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgHandle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor,
6728474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                        Handle<Object> value) {
6729474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // Dictionaries can store any property value.
6730474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (map->is_dictionary_map()) return map;
6731474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6732474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // Migrate to the newest map before storing the property.
6733a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  map = Update(map);
6734474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6735474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  Handle<DescriptorArray> descriptors(map->instance_descriptors());
6736474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6737474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (descriptors->CanHoldValue(descriptor, *value)) return map;
6738474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6739474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  Isolate* isolate = map->GetIsolate();
6740474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  Representation representation = value->OptimalRepresentation();
6741474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  Handle<HeapType> type = value->OptimalType(isolate, representation);
6742474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6743474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  return GeneralizeRepresentation(map, descriptor, representation, type,
6744474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                  FORCE_FIELD);
6745474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org}
6746474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6747474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6748474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgHandle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
6749474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                          Handle<Object> value,
6750474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                          PropertyAttributes attributes,
6751474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                          StoreFromKeyed store_mode) {
6752474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  // Dictionary maps can always have additional data properties.
6753474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (map->is_dictionary_map()) return map;
6754474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6755a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // Migrate to the newest map before storing the property.
6756a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  map = Update(map);
6757474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6758474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  int index = map->SearchTransition(*name);
6759474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (index != TransitionArray::kNotFound) {
6760474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    Handle<Map> transition(map->GetTransition(index));
6761474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    int descriptor = transition->LastAdded();
6762474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6763474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    // TODO(verwaest): Handle attributes better.
6764474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    DescriptorArray* descriptors = transition->instance_descriptors();
6765474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    if (descriptors->GetDetails(descriptor).attributes() != attributes) {
6766a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES);
6767474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    }
6768474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6769474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    return Map::PrepareForDataProperty(transition, descriptor, value);
6770474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  }
6771474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6772474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  TransitionFlag flag = INSERT_TRANSITION;
6773474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  MaybeHandle<Map> maybe_map;
6774474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (value->IsJSFunction()) {
6775474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag);
6776474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  } else if (!map->TooManyFastProperties(store_mode)) {
6777474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    Isolate* isolate = name->GetIsolate();
6778474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    Representation representation = value->OptimalRepresentation();
6779474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    Handle<HeapType> type = value->OptimalType(isolate, representation);
6780474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    maybe_map =
6781474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        Map::CopyWithField(map, name, type, attributes, representation, flag);
6782474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  }
6783474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6784474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  Handle<Map> result;
6785474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (!maybe_map.ToHandle(&result)) {
6786474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES);
6787474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  }
6788474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6789474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  return result;
6790474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org}
6791474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
6792474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
67935e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgHandle<Map> Map::ReconfigureDataProperty(Handle<Map> map, int descriptor,
67945e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                                         PropertyAttributes attributes) {
67955e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // Dictionaries have to be reconfigured in-place.
67965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  DCHECK(!map->is_dictionary_map());
67975e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
67985e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // For now, give up on transitioning and just create a unique map.
67995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // TODO(verwaest/ishell): Cache transitions with different attributes.
68005e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return CopyGeneralizeAllRepresentations(map, descriptor, FORCE_FIELD,
68015e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                                          attributes, "attributes mismatch");
68025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
68035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
68045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
68057dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.orgHandle<Map> Map::TransitionToAccessorProperty(Handle<Map> map,
68067dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org                                              Handle<Name> name,
68077dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org                                              AccessorComponent component,
68087dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org                                              Handle<Object> accessor,
68097dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org                                              PropertyAttributes attributes) {
68107dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  Isolate* isolate = name->GetIsolate();
68117dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68127dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  // Dictionary maps can always have additional data properties.
68137dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  if (map->is_dictionary_map()) {
68147dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    // For global objects, property cells are inlined. We need to change the
68157dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    // map.
68167dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    if (map->IsGlobalObjectMap()) return Copy(map);
68177dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    return map;
68187dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  }
68197dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68207dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  // Migrate to the newest map before transitioning to the new property.
6821a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  map = Update(map);
68227dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68237dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  PropertyNormalizationMode mode = map->is_prototype_map()
68247dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org                                       ? KEEP_INOBJECT_PROPERTIES
68257dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org                                       : CLEAR_INOBJECT_PROPERTIES;
68267dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68277dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  int index = map->SearchTransition(*name);
68287dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  if (index != TransitionArray::kNotFound) {
68297dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    Handle<Map> transition(map->GetTransition(index));
68307dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    DescriptorArray* descriptors = transition->instance_descriptors();
68317dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    // Fast path, assume that we're modifying the last added descriptor.
68327dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    int descriptor = transition->LastAdded();
68337dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    if (descriptors->GetKey(descriptor) != *name) {
68347dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      // If not, search for the descriptor.
68357dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      descriptor = descriptors->SearchWithCache(*name, *transition);
68367dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    }
68377dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68387dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    if (descriptors->GetDetails(descriptor).type() != CALLBACKS) {
68397dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      return Map::Normalize(map, mode);
68407dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    }
68417dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68427dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    // TODO(verwaest): Handle attributes better.
68437dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    if (descriptors->GetDetails(descriptor).attributes() != attributes) {
68447dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      return Map::Normalize(map, mode);
68457dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    }
68467dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68477dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate);
68487dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    if (!maybe_pair->IsAccessorPair()) {
68497dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      return Map::Normalize(map, mode);
68507dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    }
68517dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68527dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair);
68537dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    if (pair->get(component) != *accessor) {
68547dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      return Map::Normalize(map, mode);
68557dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    }
68567dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68577dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    return transition;
68587dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  }
68597dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68607dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  Handle<AccessorPair> pair;
68617dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  DescriptorArray* old_descriptors = map->instance_descriptors();
68627dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  int descriptor = old_descriptors->SearchWithCache(*name, *map);
68637dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  if (descriptor != DescriptorArray::kNotFound) {
68647dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    PropertyDetails old_details = old_descriptors->GetDetails(descriptor);
68657dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    if (old_details.type() != CALLBACKS) {
68667dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      return Map::Normalize(map, mode);
68677dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    }
68687dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68697dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    if (old_details.attributes() != attributes) {
68707dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      return Map::Normalize(map, mode);
68717dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    }
68727dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68737dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate);
68747dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    if (!maybe_pair->IsAccessorPair()) {
68757dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      return Map::Normalize(map, mode);
68767dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    }
68777dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68787dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    Object* current = Handle<AccessorPair>::cast(maybe_pair)->get(component);
68797dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    if (current == *accessor) return map;
68807dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68817dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    if (!current->IsTheHole()) {
68827dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      return Map::Normalize(map, mode);
68837dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    }
68847dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68857dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    pair = AccessorPair::Copy(Handle<AccessorPair>::cast(maybe_pair));
68867dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors ||
68877dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org             map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) {
68887dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES);
68897dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  } else {
68907dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    pair = isolate->factory()->NewAccessorPair();
68917dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  }
68927dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68937dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  pair->set(component, *accessor);
68947dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  TransitionFlag flag = INSERT_TRANSITION;
68957dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  CallbacksDescriptor new_desc(name, pair, attributes);
68967dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  return Map::CopyInsertDescriptor(map, &new_desc, flag);
68977dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org}
68987dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
68997dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
69005b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgHandle<Map> Map::CopyAddDescriptor(Handle<Map> map,
69015b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                   Descriptor* descriptor,
69025b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                   TransitionFlag flag) {
69035b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<DescriptorArray> descriptors(map->instance_descriptors());
6904304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
6905750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Ensure the key is unique.
69065b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  descriptor->KeyToUniqueName();
6907304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
690806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  if (flag == INSERT_TRANSITION &&
69095b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      map->owns_descriptors() &&
69105b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      map->CanHaveMoreTransitions()) {
6911c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    return ShareDescriptor(map, descriptors, descriptor);
691206ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  }
6913304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
6914202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
6915202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      descriptors, map->NumberOfOwnDescriptors(), 1);
6916202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  new_descriptors->Append(descriptor);
6917304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
6918c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  return CopyReplaceDescriptors(
6919202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      map, new_descriptors, flag, descriptor->GetKey(), SIMPLE_TRANSITION);
6920753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org}
6921753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
6922753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
69235b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgHandle<Map> Map::CopyInsertDescriptor(Handle<Map> map,
69245b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                      Descriptor* descriptor,
69255b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                      TransitionFlag flag) {
69265b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<DescriptorArray> old_descriptors(map->instance_descriptors());
6927753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
6928750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Ensure the key is unique.
69295b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  descriptor->KeyToUniqueName();
6930753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
6931753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  // We replace the key if it is already present.
69325b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  int index = old_descriptors->SearchWithCache(*descriptor->GetKey(), *map);
6933304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  if (index != DescriptorArray::kNotFound) {
6934c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    return CopyReplaceDescriptor(map, old_descriptors, descriptor, index, flag);
6935657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  }
6936c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  return CopyAddDescriptor(map, descriptor, flag);
6937753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org}
6938753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
6939753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
69405b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgHandle<DescriptorArray> DescriptorArray::CopyUpTo(
6941528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<DescriptorArray> desc,
6942202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    int enumeration_index,
6943202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    int slack) {
6944202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  return DescriptorArray::CopyUpToAddAttributes(
6945202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      desc, enumeration_index, NONE, slack);
6946528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org}
6947528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
6948528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
69495b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgHandle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
69505b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    Handle<DescriptorArray> desc,
69515b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    int enumeration_index,
6952202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    PropertyAttributes attributes,
6953202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    int slack) {
6954202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  if (enumeration_index + slack == 0) {
69555b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    return desc->GetIsolate()->factory()->empty_descriptor_array();
69565b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  }
695706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
695806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  int size = enumeration_index;
695906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
69605b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<DescriptorArray> descriptors =
69612ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      DescriptorArray::Allocate(desc->GetIsolate(), size, slack);
69625b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  DescriptorArray::WhitenessWitness witness(*descriptors);
696306ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
6964a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  if (attributes != NONE) {
6965a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    for (int i = 0; i < size; ++i) {
69665b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      Object* value = desc->GetValue(i);
696758a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org      Name* key = desc->GetKey(i);
69685b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      PropertyDetails details = desc->GetDetails(i);
696958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org      // Bulk attribute changes never affect private properties.
697058a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org      if (!key->IsSymbol() || !Symbol::cast(key)->is_private()) {
697158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org        int mask = DONT_DELETE | DONT_ENUM;
697258a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org        // READ_ONLY is an invalid attribute for JS setters/getters.
697358a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org        if (details.type() != CALLBACKS || !value->IsAccessorPair()) {
697458a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org          mask |= READ_ONLY;
697558a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org        }
697658a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org        details = details.CopyAddAttributes(
697758a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org            static_cast<PropertyAttributes>(attributes & mask));
6978a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      }
697958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org      Descriptor inner_desc(
698058a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org          handle(key), handle(value, desc->GetIsolate()), details);
69815b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      descriptors->Set(i, &inner_desc, witness);
6982a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    }
6983a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  } else {
6984a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    for (int i = 0; i < size; ++i) {
6985202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      descriptors->CopyFrom(i, *desc, witness);
6986a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    }
698706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  }
698806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
69895b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  if (desc->number_of_descriptors() != enumeration_index) descriptors->Sort();
699006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
699106ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  return descriptors;
699206ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org}
699306ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
699406ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
69955b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgHandle<Map> Map::CopyReplaceDescriptor(Handle<Map> map,
69965b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                       Handle<DescriptorArray> descriptors,
69975b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                       Descriptor* descriptor,
69985b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                       int insertion_index,
69995b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                                       TransitionFlag flag) {
7000750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Ensure the key is unique.
70015b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  descriptor->KeyToUniqueName();
7002304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
70035b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Name> key = descriptor->GetKey();
7004e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(*key == descriptors->GetKey(insertion_index));
7005304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
7006202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
7007202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      descriptors, map->NumberOfOwnDescriptors());
7008304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
7009202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  new_descriptors->Replace(insertion_index, descriptor);
7010753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
7011a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  SimpleTransitionFlag simple_flag =
7012a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      (insertion_index == descriptors->number_of_descriptors() - 1)
7013a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      ? SIMPLE_TRANSITION
7014a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      : FULL_TRANSITION;
7015c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  return CopyReplaceDescriptors(map, new_descriptors, flag, key, simple_flag);
70169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
70179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
70187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
7019394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid Map::UpdateCodeCache(Handle<Map> map,
7020750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                          Handle<Name> name,
7021394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                          Handle<Code> code) {
7022394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Isolate* isolate = map->GetIsolate();
70239fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  HandleScope scope(isolate);
7024ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Allocate the code cache if not present.
70259fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (map->code_cache()->IsFixedArray()) {
70269fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<Object> result = isolate->factory()->NewCodeCache();
70279fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    map->set_code_cache(*result);
7028ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7029ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7030ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Update the code cache.
70319fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<CodeCache> code_cache(CodeCache::cast(map->code_cache()), isolate);
70329fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  CodeCache::Update(code_cache, name, code);
7033ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7034ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7035ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7036750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgObject* Map::FindInCodeCache(Name* name, Code::Flags flags) {
7037ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Do a lookup if a code cache exists.
7038ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (!code_cache()->IsFixedArray()) {
7039ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    return CodeCache::cast(code_cache())->Lookup(name, flags);
7040ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else {
7041ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return GetHeap()->undefined_value();
7042ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7043ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7044ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7045ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
704699a37fa2988524a4a6deafb9f83a58304935af6fsgjesse@chromium.orgint Map::IndexInCodeCache(Object* name, Code* code) {
7047ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Get the internal index if a code cache exists.
7048ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (!code_cache()->IsFixedArray()) {
7049ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    return CodeCache::cast(code_cache())->GetIndex(name, code);
7050ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7051ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return -1;
7052ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7053ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7054ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7055750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid Map::RemoveFromCodeCache(Name* name, Code* code, int index) {
7056ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // No GC is supposed to happen between a call to IndexInCodeCache and
7057ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // RemoveFromCodeCache so the code cache must be there.
7058e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!code_cache()->IsFixedArray());
7059ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  CodeCache::cast(code_cache())->RemoveByIndex(name, code, index);
7060ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7061ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7062ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
70638f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org// An iterator over all map transitions in an descriptor array, reusing the
70648f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org// constructor field of the map while it is running. Negative values in
70658f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org// the constructor field indicate an active map transition iteration. The
70668f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org// original constructor is restored after iterating over all entries.
706705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.orgclass IntrusiveMapTransitionIterator {
706805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org public:
70698f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  IntrusiveMapTransitionIterator(
70708f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      Map* map, TransitionArray* transition_array, Object* constructor)
70718f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      : map_(map),
70728f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        transition_array_(transition_array),
70738f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        constructor_(constructor) { }
707405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
70758f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  void StartIfNotStarted() {
7076e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!(*IteratorField())->IsSmi() || IsIterating());
70778f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    if (!(*IteratorField())->IsSmi()) {
7078e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(*IteratorField() == constructor_);
70798f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      *IteratorField() = Smi::FromInt(-1);
70808f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    }
708105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
708205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
708305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  bool IsIterating() {
70848f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    return (*IteratorField())->IsSmi() &&
70858f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org           Smi::cast(*IteratorField())->value() < 0;
708605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
708705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
708805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  Map* Next() {
7089e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsIterating());
70908f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    int value = Smi::cast(*IteratorField())->value();
70918f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    int index = -value - 1;
709299aa490225c81012235659d9a183226b286178c8yangguo@chromium.org    int number_of_transitions = transition_array_->number_of_transitions();
709399aa490225c81012235659d9a183226b286178c8yangguo@chromium.org    while (index < number_of_transitions) {
70948f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      *IteratorField() = Smi::FromInt(value - 1);
7095753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org      return transition_array_->GetTarget(index);
70967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    }
709799aa490225c81012235659d9a183226b286178c8yangguo@chromium.org
70988f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    *IteratorField() = constructor_;
709905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    return NULL;
710005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
710105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
710205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org private:
71038f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Object** IteratorField() {
71048f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    return HeapObject::RawField(map_, Map::kConstructorOffset);
710505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
710605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
71078f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Map* map_;
710899aa490225c81012235659d9a183226b286178c8yangguo@chromium.org  TransitionArray* transition_array_;
71098f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Object* constructor_;
711005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org};
711105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
711205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
71138f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org// An iterator over all prototype transitions, reusing the constructor field
71148f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org// of the map while it is running.  Positive values in the constructor field
71158f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org// indicate an active prototype transition iteration. The original constructor
71168f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org// is restored after iterating over all entries.
711705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.orgclass IntrusivePrototypeTransitionIterator {
711805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org public:
71198f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  IntrusivePrototypeTransitionIterator(
71208f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      Map* map, HeapObject* proto_trans, Object* constructor)
71218f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      : map_(map), proto_trans_(proto_trans), constructor_(constructor) { }
712205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
71238f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  void StartIfNotStarted() {
71248f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    if (!(*IteratorField())->IsSmi()) {
7125e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(*IteratorField() == constructor_);
71268f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      *IteratorField() = Smi::FromInt(0);
71278f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    }
712805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
712905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
713005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  bool IsIterating() {
71318f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    return (*IteratorField())->IsSmi() &&
71328f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org           Smi::cast(*IteratorField())->value() >= 0;
713305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
713405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
713505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  Map* Next() {
7136e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsIterating());
71378f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    int transitionNumber = Smi::cast(*IteratorField())->value();
713805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    if (transitionNumber < NumberOfTransitions()) {
71398f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      *IteratorField() = Smi::FromInt(transitionNumber + 1);
714005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org      return GetTransition(transitionNumber);
7141d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com    }
71428f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    *IteratorField() = constructor_;
714305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    return NULL;
714405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
714505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
714605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org private:
71478f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Object** IteratorField() {
71488f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    return HeapObject::RawField(map_, Map::kConstructorOffset);
714905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
715005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
715105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  int NumberOfTransitions() {
7152212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_);
7153212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    Object* num = proto_trans->get(Map::kProtoTransitionNumberOfEntriesOffset);
715405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    return Smi::cast(num)->value();
715505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
7156d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
715705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  Map* GetTransition(int transitionNumber) {
7158212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_);
7159212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    return Map::cast(proto_trans->get(IndexFor(transitionNumber)));
716005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
716105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
716205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  int IndexFor(int transitionNumber) {
716305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    return Map::kProtoTransitionHeaderSize +
716405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org        Map::kProtoTransitionMapOffset +
716505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org        transitionNumber * Map::kProtoTransitionElementsPerEntry;
716605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
716705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
71688f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Map* map_;
7169212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  HeapObject* proto_trans_;
71708f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Object* constructor_;
717105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org};
717205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
717305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
717405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// To traverse the transition tree iteratively, we have to store two kinds of
717505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// information in a map: The parent map in the traversal and which children of a
717605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// node have already been visited. To do this without additional memory, we
71778f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org// temporarily reuse two fields with known values:
717805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org//
717905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org//  (1) The map of the map temporarily holds the parent, and is restored to the
718005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org//      meta map afterwards.
718105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org//
718205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org//  (2) The info which children have already been visited depends on which part
71838f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org//      of the map we currently iterate. We use the constructor field of the
71848f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org//      map to store the current index. We can do that because the constructor
71858f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org//      is the same for all involved maps.
718605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org//
718705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org//    (a) If we currently follow normal map transitions, we temporarily store
71888f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org//        the current index in the constructor field, and restore it to the
71898f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org//        original constructor afterwards. Note that a single descriptor can
71908f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org//        have 0, 1, or 2 transitions.
719105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org//
719205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org//    (b) If we currently follow prototype transitions, we temporarily store
71938f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org//        the current index in the constructor field, and restore it to the
71948f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org//        original constructor afterwards.
719505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org//
719605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// Note that the child iterator is just a concatenation of two iterators: One
719705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// iterating over map transitions and one iterating over prototype transisitons.
719805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.orgclass TraversableMap : public Map {
719905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org public:
720005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // Record the parent in the traversal within this map. Note that this destroys
720105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // this map's map!
720205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  void SetParent(TraversableMap* parent) { set_map_no_write_barrier(parent); }
720305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
720405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // Reset the current map's map, returning the parent previously stored in it.
720505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  TraversableMap* GetAndResetParent() {
720605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    TraversableMap* old_parent = static_cast<TraversableMap*>(map());
720705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    set_map_no_write_barrier(GetHeap()->meta_map());
720805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    return old_parent;
720905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
721005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
721105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // If we have an unvisited child map, return that one and advance. If we have
72128f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  // none, return NULL and restore the overwritten constructor field.
72138f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  TraversableMap* ChildIteratorNext(Object* constructor) {
72148f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    if (!HasTransitionArray()) return NULL;
721581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
72168f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    TransitionArray* transition_array = transitions();
7217de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org    if (transition_array->HasPrototypeTransitions()) {
7218de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org      HeapObject* proto_transitions =
72198f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          transition_array->GetPrototypeTransitions();
72208f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      IntrusivePrototypeTransitionIterator proto_iterator(this,
72218f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                                                          proto_transitions,
72228f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                                                          constructor);
72238f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      proto_iterator.StartIfNotStarted();
7224de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org      if (proto_iterator.IsIterating()) {
7225de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org        Map* next = proto_iterator.Next();
722699aa490225c81012235659d9a183226b286178c8yangguo@chromium.org        if (next != NULL) return static_cast<TraversableMap*>(next);
722799aa490225c81012235659d9a183226b286178c8yangguo@chromium.org      }
722837141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org    }
722981cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
72308f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    IntrusiveMapTransitionIterator transition_iterator(this,
72318f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                                                       transition_array,
72328f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                                                       constructor);
72338f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    transition_iterator.StartIfNotStarted();
7234de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org    if (transition_iterator.IsIterating()) {
7235de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org      Map* next = transition_iterator.Next();
7236de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org      if (next != NULL) return static_cast<TraversableMap*>(next);
7237de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org    }
7238de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org
723905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    return NULL;
724005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
724105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org};
724205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
724305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
724405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// Traverse the transition tree in postorder without using the C++ stack by
724505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// doing pointer reversal.
724605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.orgvoid Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
72478f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  // Make sure that we do not allocate in the callback.
72488f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  DisallowHeapAllocation no_allocation;
72498f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
725005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  TraversableMap* current = static_cast<TraversableMap*>(this);
72518f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  // Get the root constructor here to restore it later when finished iterating
72528f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  // over maps.
72538f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Object* root_constructor = constructor();
725405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  while (true) {
72558f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    TraversableMap* child = current->ChildIteratorNext(root_constructor);
725605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    if (child != NULL) {
725705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org      child->SetParent(current);
725805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org      current = child;
725905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    } else {
726005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org      TraversableMap* parent = current->GetAndResetParent();
726105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org      callback(current, data);
726205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org      if (current == this) break;
726305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org      current = parent;
726405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    }
72654a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  }
72664a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org}
72674a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
72684a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
72699fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgvoid CodeCache::Update(
72709fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code) {
7271ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // The number of monomorphic stubs for normal load/store/call IC's can grow to
7272ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // a large number and therefore they need to go into a hash table. They are
7273ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // used to load global properties from cells.
72747a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  if (code->type() == Code::NORMAL) {
7275ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    // Make sure that a hash table is allocated for the normal load code cache.
72769fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (code_cache->normal_type_cache()->IsUndefined()) {
72779fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      Handle<Object> result =
72789fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          CodeCacheHashTable::New(code_cache->GetIsolate(),
72799fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                  CodeCacheHashTable::kInitialSize);
72809fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      code_cache->set_normal_type_cache(*result);
7281ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
72829fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    UpdateNormalTypeCache(code_cache, name, code);
7283ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else {
7284e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(code_cache->default_cache()->IsFixedArray());
72859fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    UpdateDefaultCache(code_cache, name, code);
7286ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7287ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7288ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7289ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
72909fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgvoid CodeCache::UpdateDefaultCache(
72919fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code) {
7292ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // When updating the default code cache we disregard the type encoded in the
729343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // flags. This allows call constant stubs to overwrite call field
729443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // stubs, etc.
729543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Code::Flags flags = Code::RemoveTypeFromFlags(code->flags());
729643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
729743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // First check whether we can update existing code cache without
729843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // extending it.
72999fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<FixedArray> cache = handle(code_cache->default_cache());
730043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int length = cache->length();
73019fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  {
73029fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    DisallowHeapAllocation no_alloc;
73039fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    int deleted_index = -1;
73049fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    for (int i = 0; i < length; i += kCodeCacheEntrySize) {
73059fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      Object* key = cache->get(i);
73069fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      if (key->IsNull()) {
73079fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        if (deleted_index < 0) deleted_index = i;
73089fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        continue;
73099fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      }
73109fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      if (key->IsUndefined()) {
73119fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        if (deleted_index >= 0) i = deleted_index;
73129fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        cache->set(i + kCodeCacheEntryNameOffset, *name);
73139fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        cache->set(i + kCodeCacheEntryCodeOffset, *code);
73149fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        return;
73159fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      }
73169fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      if (name->Equals(Name::cast(key))) {
73179fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        Code::Flags found =
73189fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org            Code::cast(cache->get(i + kCodeCacheEntryCodeOffset))->flags();
73199fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        if (Code::RemoveTypeFromFlags(found) == flags) {
73209fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          cache->set(i + kCodeCacheEntryCodeOffset, *code);
73219fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          return;
73229fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        }
732343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
732443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
732543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73269fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // Reached the end of the code cache.  If there were deleted
73279fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // elements, reuse the space for the first of them.
73289fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (deleted_index >= 0) {
73299fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      cache->set(deleted_index + kCodeCacheEntryNameOffset, *name);
73309fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      cache->set(deleted_index + kCodeCacheEntryCodeOffset, *code);
73319fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      return;
73329fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
7333236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
7334236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
7335ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Extend the code cache with some new entries (at least one). Must be a
7336ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // multiple of the entry size.
7337ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int new_length = length + ((length >> 1)) + kCodeCacheEntrySize;
7338ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  new_length = new_length - new_length % kCodeCacheEntrySize;
7339e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((new_length % kCodeCacheEntrySize) == 0);
73409fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  cache = FixedArray::CopySize(cache, new_length);
734143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
734243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the (name, code) pair to the new cache.
73439fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  cache->set(length + kCodeCacheEntryNameOffset, *name);
73449fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  cache->set(length + kCodeCacheEntryCodeOffset, *code);
73459fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  code_cache->set_default_cache(*cache);
734643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
734743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
734843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73499fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgvoid CodeCache::UpdateNormalTypeCache(
73509fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code) {
7351ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Adding a new entry can cause a new cache to be allocated.
73529fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<CodeCacheHashTable> cache(
73539fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      CodeCacheHashTable::cast(code_cache->normal_type_cache()));
73549fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<Object> new_cache = CodeCacheHashTable::Put(cache, name, code);
73559fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  code_cache->set_normal_type_cache(*new_cache);
7356ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7357ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7358ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7359750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgObject* CodeCache::Lookup(Name* name, Code::Flags flags) {
7360f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Object* result = LookupDefaultCache(name, Code::RemoveTypeFromFlags(flags));
7361f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (result->IsCode()) {
7362f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (Code::cast(result)->flags() == flags) return result;
7363f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return GetHeap()->undefined_value();
7364f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
7365d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  return LookupNormalTypeCache(name, flags);
7366ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7367ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7368ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7369750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgObject* CodeCache::LookupDefaultCache(Name* name, Code::Flags flags) {
7370ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  FixedArray* cache = default_cache();
737143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int length = cache->length();
7372ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  for (int i = 0; i < length; i += kCodeCacheEntrySize) {
7373ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    Object* key = cache->get(i + kCodeCacheEntryNameOffset);
7374236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    // Skip deleted elements.
7375236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    if (key->IsNull()) continue;
7376236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    if (key->IsUndefined()) return key;
7377750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (name->Equals(Name::cast(key))) {
7378ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset));
7379d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org      if (Code::RemoveTypeFromFlags(code->flags()) == flags) {
7380ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org        return code;
7381ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      }
738243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
738343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
7384c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  return GetHeap()->undefined_value();
738543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
738643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
738743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7388750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgObject* CodeCache::LookupNormalTypeCache(Name* name, Code::Flags flags) {
7389ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (!normal_type_cache()->IsUndefined()) {
7390ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache());
7391ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    return cache->Lookup(name, flags);
7392ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else {
7393ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return GetHeap()->undefined_value();
7394ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7395ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7396ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7397ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
739899a37fa2988524a4a6deafb9f83a58304935af6fsgjesse@chromium.orgint CodeCache::GetIndex(Object* name, Code* code) {
73997a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  if (code->type() == Code::NORMAL) {
7400ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (normal_type_cache()->IsUndefined()) return -1;
7401ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache());
7402750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    return cache->GetIndex(Name::cast(name), code->flags());
7403ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7404ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7405ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  FixedArray* array = default_cache();
740643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int len = array->length();
7407ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  for (int i = 0; i < len; i += kCodeCacheEntrySize) {
7408ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (array->get(i + kCodeCacheEntryCodeOffset) == code) return i + 1;
740943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
7410b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  return -1;
7411b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org}
7412b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org
7413b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org
741499a37fa2988524a4a6deafb9f83a58304935af6fsgjesse@chromium.orgvoid CodeCache::RemoveByIndex(Object* name, Code* code, int index) {
74157a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  if (code->type() == Code::NORMAL) {
7416e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!normal_type_cache()->IsUndefined());
7417ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache());
7418e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(cache->GetIndex(Name::cast(name), code->flags()) == index);
7419ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    cache->RemoveByIndex(index);
7420ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else {
7421ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    FixedArray* array = default_cache();
7422e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(array->length() >= index && array->get(index)->IsCode());
7423ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    // Use null instead of undefined for deleted elements to distinguish
7424ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    // deleted elements from unused elements.  This distinction is used
7425ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    // when looking up in the cache and when updating the cache.
7426e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK_EQ(1, kCodeCacheEntryCodeOffset - kCodeCacheEntryNameOffset);
7427ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    array->set_null(index - 1);  // Name.
7428ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    array->set_null(index);  // Code.
7429ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7430ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7431ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7432ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7433ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// The key in the code cache hash table consists of the property name and the
7434ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// code object. The actual match is on the name and the code flags. If a key
7435ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// is created using the flags and not a code object it can only be used for
7436ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org// lookup not to create a new entry.
7437ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgclass CodeCacheHashTableKey : public HashTableKey {
7438ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org public:
74399fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  CodeCacheHashTableKey(Handle<Name> name, Code::Flags flags)
74409fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      : name_(name), flags_(flags), code_() { }
7441ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
74429fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  CodeCacheHashTableKey(Handle<Name> name, Handle<Code> code)
7443d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org      : name_(name), flags_(code->flags()), code_(code) { }
7444ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7445ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  bool IsMatch(Object* other) OVERRIDE {
7446ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (!other->IsFixedArray()) return false;
7447ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    FixedArray* pair = FixedArray::cast(other);
7448750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Name* name = Name::cast(pair->get(0));
7449ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    Code::Flags flags = Code::cast(pair->get(1))->flags();
7450ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    if (flags != flags_) {
7451ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      return false;
7452ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    }
7453ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    return name_->Equals(name);
7454ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7455ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7456750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  static uint32_t NameFlagsHashHelper(Name* name, Code::Flags flags) {
7457ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    return name->Hash() ^ flags;
7458ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7459ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7460ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  uint32_t Hash() OVERRIDE { return NameFlagsHashHelper(*name_, flags_); }
7461ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7462ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  uint32_t HashForObject(Object* obj) OVERRIDE {
7463ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    FixedArray* pair = FixedArray::cast(obj);
7464750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Name* name = Name::cast(pair->get(0));
7465ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    Code* code = Code::cast(pair->get(1));
7466ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    return NameFlagsHashHelper(name, code->flags());
7467ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7468ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7469ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  MUST_USE_RESULT Handle<Object> AsHandle(Isolate* isolate) OVERRIDE {
74709fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<Code> code = code_.ToHandleChecked();
7471865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    Handle<FixedArray> pair = isolate->factory()->NewFixedArray(2);
74729fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    pair->set(0, *name_);
74739fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    pair->set(1, *code);
7474ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    return pair;
7475ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7476ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7477ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org private:
74789fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<Name> name_;
7479ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  Code::Flags flags_;
7480e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // TODO(jkummerow): We should be able to get by without this.
74819fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  MaybeHandle<Code> code_;
7482ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org};
7483ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7484ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7485750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgObject* CodeCacheHashTable::Lookup(Name* name, Code::Flags flags) {
74869fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  DisallowHeapAllocation no_alloc;
74879fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  CodeCacheHashTableKey key(handle(name), flags);
7488ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int entry = FindEntry(&key);
7489ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (entry == kNotFound) return GetHeap()->undefined_value();
7490ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return get(EntryToIndex(entry) + 1);
7491ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7492ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7493ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
74949fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgHandle<CodeCacheHashTable> CodeCacheHashTable::Put(
74959fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<CodeCacheHashTable> cache, Handle<Name> name, Handle<Code> code) {
7496ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  CodeCacheHashTableKey key(name, code);
7497ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
74989fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<CodeCacheHashTable> new_cache = EnsureCapacity(cache, 1, &key);
7499ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
75009fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int entry = new_cache->FindInsertionEntry(key.Hash());
7501865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Handle<Object> k = key.AsHandle(cache->GetIsolate());
7502ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
75039fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  new_cache->set(EntryToIndex(entry), *k);
75049fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  new_cache->set(EntryToIndex(entry) + 1, *code);
75059fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  new_cache->ElementAdded();
75069fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return new_cache;
7507ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7508ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7509ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7510750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgint CodeCacheHashTable::GetIndex(Name* name, Code::Flags flags) {
75119fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  DisallowHeapAllocation no_alloc;
75129fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  CodeCacheHashTableKey key(handle(name), flags);
7513ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int entry = FindEntry(&key);
7514ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return (entry == kNotFound) ? -1 : entry;
7515ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
7516ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7517ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
7518ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid CodeCacheHashTable::RemoveByIndex(int index) {
7519e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index >= 0);
7520ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = GetHeap();
7521c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  set(EntryToIndex(index), heap->the_hole_value());
7522c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  set(EntryToIndex(index) + 1, heap->the_hole_value());
7523ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ElementRemoved();
752443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
752543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
752643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75278496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.orgvoid PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> code_cache,
7528394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                  MapHandleList* maps,
7529394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                  Code::Flags flags,
7530394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                  Handle<Code> code) {
75318496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Isolate* isolate = code_cache->GetIsolate();
75328496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  if (code_cache->cache()->IsUndefined()) {
75338496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    Handle<PolymorphicCodeCacheHashTable> result =
75348496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        PolymorphicCodeCacheHashTable::New(
75358496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org            isolate,
75368496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org            PolymorphicCodeCacheHashTable::kInitialSize);
75378496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    code_cache->set_cache(*result);
7538e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  } else {
7539e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    // This entry shouldn't be contained in the cache yet.
7540e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(PolymorphicCodeCacheHashTable::cast(code_cache->cache())
7541e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org               ->Lookup(maps, flags)->IsUndefined());
7542e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
75438496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<PolymorphicCodeCacheHashTable> hash_table =
75448496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      handle(PolymorphicCodeCacheHashTable::cast(code_cache->cache()));
75458496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<PolymorphicCodeCacheHashTable> new_cache =
75468496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      PolymorphicCodeCacheHashTable::Put(hash_table, maps, flags, code);
75478496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  code_cache->set_cache(*new_cache);
7548e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org}
7549e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7550e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7551394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Object> PolymorphicCodeCache::Lookup(MapHandleList* maps,
7552394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                            Code::Flags flags) {
7553e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  if (!cache()->IsUndefined()) {
7554e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    PolymorphicCodeCacheHashTable* hash_table =
7555e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org        PolymorphicCodeCacheHashTable::cast(cache());
755609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    return Handle<Object>(hash_table->Lookup(maps, flags), GetIsolate());
7557e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  } else {
7558394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return GetIsolate()->factory()->undefined_value();
7559e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
7560e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org}
7561e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7562e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7563e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org// Despite their name, object of this class are not stored in the actual
7564e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org// hash table; instead they're temporarily used for lookups. It is therefore
7565e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org// safe to have a weak (non-owning) pointer to a MapList as a member field.
7566e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgclass PolymorphicCodeCacheHashTableKey : public HashTableKey {
7567e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org public:
7568e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // Callers must ensure that |maps| outlives the newly constructed object.
7569865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  PolymorphicCodeCacheHashTableKey(MapHandleList* maps, int code_flags)
7570865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      : maps_(maps),
7571e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org        code_flags_(code_flags) {}
7572e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7573ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  bool IsMatch(Object* other) OVERRIDE {
7574394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    MapHandleList other_maps(kDefaultListAllocationSize);
7575e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    int other_flags;
7576e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    FromObject(other, &other_flags, &other_maps);
7577e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    if (code_flags_ != other_flags) return false;
7578e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    if (maps_->length() != other_maps.length()) return false;
7579e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    // Compare just the hashes first because it's faster.
7580e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    int this_hash = MapsHashHelper(maps_, code_flags_);
7581e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    int other_hash = MapsHashHelper(&other_maps, other_flags);
7582e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    if (this_hash != other_hash) return false;
7583e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7584e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    // Full comparison: for each map in maps_, look for an equivalent map in
7585e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    // other_maps. This implementation is slow, but probably good enough for
7586e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    // now because the lists are short (<= 4 elements currently).
7587e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    for (int i = 0; i < maps_->length(); ++i) {
7588e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      bool match_found = false;
7589e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      for (int j = 0; j < other_maps.length(); ++j) {
759078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        if (*(maps_->at(i)) == *(other_maps.at(j))) {
7591e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org          match_found = true;
7592e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org          break;
7593e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org        }
7594e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      }
7595e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      if (!match_found) return false;
7596e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    }
7597e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    return true;
7598e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
7599e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7600394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  static uint32_t MapsHashHelper(MapHandleList* maps, int code_flags) {
7601e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    uint32_t hash = code_flags;
7602e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    for (int i = 0; i < maps->length(); ++i) {
7603e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      hash ^= maps->at(i)->Hash();
7604e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    }
7605e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    return hash;
7606e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
7607e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7608ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  uint32_t Hash() OVERRIDE {
7609e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    return MapsHashHelper(maps_, code_flags_);
7610e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
7611e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7612ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  uint32_t HashForObject(Object* obj) OVERRIDE {
7613394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    MapHandleList other_maps(kDefaultListAllocationSize);
7614e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    int other_flags;
7615e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    FromObject(obj, &other_flags, &other_maps);
7616e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    return MapsHashHelper(&other_maps, other_flags);
7617e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
7618e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7619ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  MUST_USE_RESULT Handle<Object> AsHandle(Isolate* isolate) OVERRIDE {
7620e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    // The maps in |maps_| must be copied to a newly allocated FixedArray,
7621e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    // both because the referenced MapList is short-lived, and because C++
7622e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    // objects can't be stored in the heap anyway.
7623865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    Handle<FixedArray> list =
7624865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org        isolate->factory()->NewUninitializedFixedArray(maps_->length() + 1);
7625e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    list->set(0, Smi::FromInt(code_flags_));
7626e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    for (int i = 0; i < maps_->length(); ++i) {
7627394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      list->set(i + 1, *maps_->at(i));
7628e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    }
7629e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    return list;
7630e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
7631e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7632e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org private:
7633394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  static MapHandleList* FromObject(Object* obj,
7634394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                   int* code_flags,
7635394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                   MapHandleList* maps) {
7636e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    FixedArray* list = FixedArray::cast(obj);
7637e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    maps->Rewind(0);
7638e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    *code_flags = Smi::cast(list->get(0))->value();
7639e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    for (int i = 1; i < list->length(); ++i) {
7640394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      maps->Add(Handle<Map>(Map::cast(list->get(i))));
7641e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    }
7642e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    return maps;
7643e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
7644e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7645394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  MapHandleList* maps_;  // weak.
7646e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  int code_flags_;
76477b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  static const int kDefaultListAllocationSize = kMaxKeyedPolymorphism + 1;
7648e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org};
7649e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7650e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7651394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comObject* PolymorphicCodeCacheHashTable::Lookup(MapHandleList* maps,
76528496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                              int code_kind) {
76538496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  DisallowHeapAllocation no_alloc;
7654865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  PolymorphicCodeCacheHashTableKey key(maps, code_kind);
7655e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  int entry = FindEntry(&key);
7656e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  if (entry == kNotFound) return GetHeap()->undefined_value();
7657e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  return get(EntryToIndex(entry) + 1);
7658e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org}
7659e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7660e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
76618496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.orgHandle<PolymorphicCodeCacheHashTable> PolymorphicCodeCacheHashTable::Put(
76628496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      Handle<PolymorphicCodeCacheHashTable> hash_table,
76638496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      MapHandleList* maps,
76648496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      int code_kind,
76658496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      Handle<Code> code) {
7666865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  PolymorphicCodeCacheHashTableKey key(maps, code_kind);
76678496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  Handle<PolymorphicCodeCacheHashTable> cache =
76688496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      EnsureCapacity(hash_table, 1, &key);
7669e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  int entry = cache->FindInsertionEntry(key.Hash());
76708496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
7671865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Handle<Object> obj = key.AsHandle(hash_table->GetIsolate());
76728496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  cache->set(EntryToIndex(entry), *obj);
76738496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  cache->set(EntryToIndex(entry) + 1, *code);
7674e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  cache->ElementAdded();
7675e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  return cache;
7676e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org}
7677e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7678e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
76796d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgvoid FixedArray::Shrink(int new_length) {
7680e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(0 <= new_length && new_length <= length());
76816d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  if (new_length < length()) {
76823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GetHeap()->RightTrimFixedArray<Heap::FROM_MUTATOR>(
76833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        this, length() - new_length);
76846d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  }
76856d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org}
76866d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org
76876d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org
76883484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgMaybeHandle<FixedArray> FixedArray::AddKeysFromArrayLike(
7689202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    Handle<FixedArray> content,
76903484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    Handle<JSObject> array) {
7691e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(array->IsJSArray() || array->HasSloppyArgumentsElements());
76924acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  ElementsAccessor* accessor = array->GetElementsAccessor();
7693202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<FixedArray> result;
7694202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
7695202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      array->GetIsolate(), result,
7696202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      accessor->AddElementsToFixedArray(array, array, content),
7697202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      FixedArray);
76988f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
7699e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org#ifdef ENABLE_SLOW_DCHECKS
77004acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  if (FLAG_enable_slow_asserts) {
77018f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    DisallowHeapAllocation no_allocation;
77024acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    for (int i = 0; i < result->length(); i++) {
77034acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      Object* current = result->get(i);
7704e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(current->IsNumber() || current->IsName());
77054acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    }
77064acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  }
77074acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org#endif
77084acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  return result;
770943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
771043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
771143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7712202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.orgMaybeHandle<FixedArray> FixedArray::UnionOfKeys(Handle<FixedArray> first,
7713202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org                                                Handle<FixedArray> second) {
77148f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  ElementsAccessor* accessor = ElementsAccessor::ForArray(second);
7715202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<FixedArray> result;
7716202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
7717202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      first->GetIsolate(), result,
77188f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      accessor->AddElementsToFixedArray(
77198f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          Handle<Object>::null(),     // receiver
77208f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          Handle<JSObject>::null(),   // holder
77218f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org          first,
7722202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org          Handle<FixedArrayBase>::cast(second)),
7723202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      FixedArray);
77248f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
7725e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org#ifdef ENABLE_SLOW_DCHECKS
7726b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org  if (FLAG_enable_slow_asserts) {
77278f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    DisallowHeapAllocation no_allocation;
772828a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org    for (int i = 0; i < result->length(); i++) {
772928a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org      Object* current = result->get(i);
7730e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(current->IsNumber() || current->IsName());
7731b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org    }
7732b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org  }
7733b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org#endif
773443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
773543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
773643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
773743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77383484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgHandle<FixedArray> FixedArray::CopySize(
77393484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    Handle<FixedArray> array, int new_length, PretenureFlag pretenure) {
77403484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Isolate* isolate = array->GetIsolate();
77413484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  if (new_length == 0) return isolate->factory()->empty_fixed_array();
77423484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<FixedArray> result =
77433484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      isolate->factory()->NewFixedArray(new_length, pretenure);
774443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Copy the content
774579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
77463484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  int len = array->length();
774743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (new_length < len) len = new_length;
774864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // We are taking the map from the old fixed array so the map is sure to
774964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // be an immortal immutable object.
77503484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  result->set_map_no_write_barrier(array->map());
7751b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
775243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < len; i++) {
77533484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    result->set(i, array->get(i), mode);
775443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
775543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
775643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
775743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
775843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
775943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, int len) {
776079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
7761b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc);
776243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int index = 0; index < len; index++) {
776343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    dest->set(dest_pos+index, get(pos+index), mode);
776443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
776543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
776643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
776743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
77689a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#ifdef DEBUG
77699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.combool FixedArray::IsEqualTo(FixedArray* other) {
77709a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (length() != other->length()) return false;
77719a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  for (int i = 0 ; i < length(); ++i) {
77729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    if (get(i) != other->get(i)) return false;
77739a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
77749a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  return true;
77759a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
77769a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#endif
77779a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
77789a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
77792ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgHandle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
77802ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                                  int number_of_descriptors,
77812ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                                  int slack) {
7782e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(0 <= number_of_descriptors);
77832ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Factory* factory = isolate->factory();
77847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // Do not use DescriptorArray::cast on incomplete object.
778533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  int size = number_of_descriptors + slack;
77862ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (size == 0) return factory->empty_descriptor_array();
77875091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org  // Allocate the array of keys.
77882ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<FixedArray> result = factory->NewFixedArray(LengthFor(size));
77895091559f9e984140e5a1d0fe4951ad435866e0e4verwaest@chromium.org
779033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
7791304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  result->set(kEnumCacheIndex, Smi::FromInt(0));
77922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return Handle<DescriptorArray>::cast(result);
779343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
779443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
779543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
779606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.orgvoid DescriptorArray::ClearEnumCache() {
779706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  set(kEnumCacheIndex, Smi::FromInt(0));
779806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org}
779906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
780006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
7801202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.orgvoid DescriptorArray::Replace(int index, Descriptor* descriptor) {
7802202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index));
7803202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Set(index, descriptor);
7804202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org}
7805202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org
7806202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org
780743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
7808be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                                   FixedArray* new_cache,
7809be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                                   Object* new_index_cache) {
7810e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(bridge_storage->length() >= kEnumCacheBridgeLength);
7811e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(new_index_cache->IsSmi() || new_index_cache->IsFixedArray());
7812e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsEmpty());
7813e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!HasEnumCache() || new_cache->length() > GetEnumCache()->length());
7814c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  FixedArray::cast(bridge_storage)->
7815c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    set(kEnumCacheBridgeCacheIndex, new_cache);
7816c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  FixedArray::cast(bridge_storage)->
7817c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache);
7818c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  set(kEnumCacheIndex, bridge_storage);
781943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
782043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
782143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7822202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.orgvoid DescriptorArray::CopyFrom(int index,
7823753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org                               DescriptorArray* src,
782465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org                               const WhitenessWitness& witness) {
7825202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Object* value = src->GetValue(index);
7826202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  PropertyDetails details = src->GetDetails(index);
7827202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Descriptor desc(handle(src->GetKey(index)),
78285b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                  handle(value, src->GetIsolate()),
78295b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                  details);
7830202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Set(index, &desc, witness);
783165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org}
783265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org
783343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
783437141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org// We need the whiteness witness since sort will reshuffle the entries in the
783537141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org// descriptor array. If the descriptor array were to be black, the shuffling
783637141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org// would move a slot that was already recorded as pointing into an evacuation
783737141398d9125c021d47ceb91e2b19efd35c89ddverwaest@chromium.org// candidate. This would result in missing updates upon evacuation.
783846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid DescriptorArray::Sort() {
783943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // In-place heap sort.
784043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int len = number_of_descriptors();
784146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Reset sorting since the descriptor array might contain invalid pointers.
784246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  for (int i = 0; i < len; ++i) SetSortedKey(i, i);
784343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Bottom-up max-heap construction.
7844ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Index of the last node with children
7845ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  const int max_parent_index = (len / 2) - 1;
7846ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  for (int i = max_parent_index; i >= 0; --i) {
7847ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    int parent_index = i;
784846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    const uint32_t parent_hash = GetSortedKey(i)->Hash();
7849ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    while (parent_index <= max_parent_index) {
7850ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      int child_index = 2 * parent_index + 1;
785146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      uint32_t child_hash = GetSortedKey(child_index)->Hash();
7852ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      if (child_index + 1 < len) {
785346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
7854ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org        if (right_child_hash > child_hash) {
7855ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org          child_index++;
7856ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org          child_hash = right_child_hash;
7857ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org        }
785843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
7859ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      if (child_hash <= parent_hash) break;
786046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      SwapSortedKeys(parent_index, child_index);
7861ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      // Now element at child_index could be < its children.
7862ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      parent_index = child_index;  // parent_hash remains correct.
786343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
786443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
786543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
786643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Extract elements and create sorted array.
786743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = len - 1; i > 0; --i) {
786843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Put max element at the back of the array.
786946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    SwapSortedKeys(0, i);
7870394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // Shift down the new top element.
787143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int parent_index = 0;
787246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    const uint32_t parent_hash = GetSortedKey(parent_index)->Hash();
7873ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    const int max_parent_index = (i / 2) - 1;
7874ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    while (parent_index <= max_parent_index) {
7875ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      int child_index = parent_index * 2 + 1;
787646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      uint32_t child_hash = GetSortedKey(child_index)->Hash();
7877ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      if (child_index + 1 < i) {
787846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        uint32_t right_child_hash = GetSortedKey(child_index + 1)->Hash();
7879ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org        if (right_child_hash > child_hash) {
7880ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org          child_index++;
7881ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org          child_hash = right_child_hash;
7882ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org        }
788343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
7884ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      if (child_hash <= parent_hash) break;
788546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      SwapSortedKeys(parent_index, child_index);
7886ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      parent_index = child_index;
788743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
788843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
7889e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsSortedNoDuplicates());
789043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
789143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
789243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7893c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgHandle<AccessorPair> AccessorPair::Copy(Handle<AccessorPair> pair) {
7894c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  Handle<AccessorPair> copy = pair->GetIsolate()->factory()->NewAccessorPair();
7895c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  copy->set_getter(pair->getter());
7896c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  copy->set_setter(pair->setter());
789765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org  return copy;
789865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org}
789965a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org
790065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org
790188aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.orgObject* AccessorPair::GetComponent(AccessorComponent component) {
7902830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  Object* accessor = get(component);
7903830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor;
7904bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com}
7905bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
7906bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
79073484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgHandle<DeoptimizationInputData> DeoptimizationInputData::New(
79086474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    Isolate* isolate, int deopt_entry_count, PretenureFlag pretenure) {
79096474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  DCHECK(deopt_entry_count > 0);
79106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  return Handle<DeoptimizationInputData>::cast(
79116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      isolate->factory()->NewFixedArray(LengthFor(deopt_entry_count),
79126474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                        pretenure));
7913a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
7914a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7915a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
79163484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgHandle<DeoptimizationOutputData> DeoptimizationOutputData::New(
79173484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    Isolate* isolate,
79183484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    int number_of_deopt_points,
79193484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    PretenureFlag pretenure) {
79203484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<FixedArray> result;
79213484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  if (number_of_deopt_points == 0) {
79223484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    result = isolate->factory()->empty_fixed_array();
79233484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  } else {
79243484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    result = isolate->factory()->NewFixedArray(
79253484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org        LengthOfFixedArray(number_of_deopt_points), pretenure);
79263484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  }
79273484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  return Handle<DeoptimizationOutputData>::cast(result);
7928a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
7929a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7930a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
79319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#ifdef DEBUG
79329a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.combool DescriptorArray::IsEqualTo(DescriptorArray* other) {
79339a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (IsEmpty()) return other->IsEmpty();
79349a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (other->IsEmpty()) return false;
79359a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (length() != other->length()) return false;
79369a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  for (int i = 0; i < length(); ++i) {
7937400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org    if (get(i) != other->get(i)) return false;
79389a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
7939400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  return true;
79409a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
79419a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#endif
79429a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
79439a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
794443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool String::LooksValid() {
79453d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  if (!GetIsolate()->heap()->Contains(this)) return false;
7946870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  return true;
794743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
794843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
794943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7950ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.orgString::FlatContent String::GetFlatContent() {
7951e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!AllowHeapAllocation::IsAllowed());
7952bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int length = this->length();
7953ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  StringShape shape(this);
79547c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  String* string = this;
79554668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  int offset = 0;
7956ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  if (shape.representation_tag() == kConsStringTag) {
79575a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    ConsString* cons = ConsString::cast(string);
7958ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (cons->second()->length() != 0) {
7959ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      return FlatContent();
7960ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    }
7961870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    string = cons->first();
7962ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    shape = StringShape(string);
79637c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  }
79644668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  if (shape.representation_tag() == kSlicedStringTag) {
79654668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    SlicedString* slice = SlicedString::cast(string);
79664668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    offset = slice->offset();
79674668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    string = slice->parent();
79684668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    shape = StringShape(string);
7969e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(shape.representation_tag() != kConsStringTag &&
79704668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org           shape.representation_tag() != kSlicedStringTag);
79714668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  }
7972e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (shape.encoding_tag() == kOneByteStringTag) {
797359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    const uint8_t* start;
7974ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (shape.representation_tag() == kSeqStringTag) {
7975fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      start = SeqOneByteString::cast(string)->GetChars();
7976ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    } else {
79772c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      start = ExternalOneByteString::cast(string)->GetChars();
7978ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    }
79792ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    return FlatContent(start + offset, length);
7980ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  } else {
7981e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(shape.encoding_tag() == kTwoByteStringTag);
7982ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    const uc16* start;
7983ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    if (shape.representation_tag() == kSeqStringTag) {
7984ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org      start = SeqTwoByteString::cast(string)->GetChars();
7985ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    } else {
79860ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry      start = ExternalTwoByteString::cast(string)->GetChars();
7987ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    }
79882ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    return FlatContent(start + offset, length);
79897c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  }
79907c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org}
79917c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
79927c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
799383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.orgSmartArrayPointer<char> String::ToCString(AllowNullsFlag allow_nulls,
799483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org                                          RobustnessFlag robust_flag,
799583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org                                          int offset,
799683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org                                          int length,
799783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org                                          int* length_return) {
799843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
799983e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    return SmartArrayPointer<char>(NULL);
800043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
8001ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = GetHeap();
800243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
800343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Negative length means the to the end of the string.
800443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (length < 0) length = kMaxInt - offset;
800543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
800643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute the size of the UTF-8 string. Start at the specified offset.
80074cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  Access<ConsStringIteratorOp> op(
80084cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      heap->isolate()->objects_string_iterator());
80094cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  StringCharacterStream stream(this, op.value(), offset);
801043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int character_position = offset;
801143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int utf8_bytes = 0;
8012154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  int last = unibrow::Utf16::kNoPreviousCharacter;
80134cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  while (stream.HasMore() && character_position++ < offset + length) {
80144cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    uint16_t character = stream.GetNext();
8015154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    utf8_bytes += unibrow::Utf8::Length(character, last);
8016154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    last = character;
801743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
801843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
801943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (length_return) {
802043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    *length_return = utf8_bytes;
802143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
802243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
802343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  char* result = NewArray<char>(utf8_bytes + 1);
802443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
802543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Convert the UTF-16 string to a UTF-8 buffer. Start at the specified offset.
80264cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  stream.Reset(this, offset);
802743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  character_position = offset;
802843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int utf8_byte_position = 0;
8029154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  last = unibrow::Utf16::kNoPreviousCharacter;
80304cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  while (stream.HasMore() && character_position++ < offset + length) {
80314cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    uint16_t character = stream.GetNext();
8032c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    if (allow_nulls == DISALLOW_NULLS && character == 0) {
8033c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      character = ' ';
803443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
8035c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    utf8_byte_position +=
8036154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org        unibrow::Utf8::Encode(result + utf8_byte_position, character, last);
8037154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    last = character;
803843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
803943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  result[utf8_byte_position] = 0;
804083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  return SmartArrayPointer<char>(result);
804143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
804243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
804343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
804483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.orgSmartArrayPointer<char> String::ToCString(AllowNullsFlag allow_nulls,
804583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org                                          RobustnessFlag robust_flag,
804683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org                                          int* length_return) {
804743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return ToCString(allow_nulls, robust_flag, 0, -1, length_return);
804843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
804943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
805043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
805143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst uc16* String::GetTwoByteData(unsigned start) {
8052e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsOneByteRepresentationUnderneath());
8053bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  switch (StringShape(this).representation_tag()) {
805443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case kSeqStringTag:
80557c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org      return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start);
805643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case kExternalStringTag:
805743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return ExternalTwoByteString::cast(this)->
805843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        ExternalTwoByteStringGetData(start);
80594668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    case kSlicedStringTag: {
80604668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      SlicedString* slice = SlicedString::cast(this);
80614668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      return slice->parent()->GetTwoByteData(start + slice->offset());
80624668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    }
806343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    case kConsStringTag:
806443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      UNREACHABLE();
806543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return NULL;
806643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
806743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  UNREACHABLE();
806843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return NULL;
806943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
807043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
807143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
807283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.orgSmartArrayPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) {
807343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
807483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    return SmartArrayPointer<uc16>();
807543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
8076ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = GetHeap();
807743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
80784cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  Access<ConsStringIteratorOp> op(
80794cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      heap->isolate()->objects_string_iterator());
80804cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  StringCharacterStream stream(this, op.value());
808143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
808243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uc16* result = NewArray<uc16>(length() + 1);
808343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
808443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int i = 0;
80854cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  while (stream.HasMore()) {
80864cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    uint16_t character = stream.GetNext();
808743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    result[i++] = character;
808843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
808943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  result[i] = 0;
809083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  return SmartArrayPointer<uc16>(result);
809143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
809243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
809343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
80947c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.orgconst uc16* SeqTwoByteString::SeqTwoByteStringGetData(unsigned start) {
809543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return reinterpret_cast<uc16*>(
809643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      reinterpret_cast<char*>(this) - kHeapObjectTag + kHeaderSize) + start;
809743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
809843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
809943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
81003d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid Relocatable::PostGarbageCollectionProcessing(Isolate* isolate) {
8101ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Relocatable* current = isolate->relocatable_top();
8102c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  while (current != NULL) {
8103c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    current->PostGarbageCollection();
8104c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    current = current->prev_;
8105c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  }
8106c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
8107c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
8108c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
8109c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// Reserve space for statics needing saving and restoring.
8110c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgint Relocatable::ArchiveSpacePerThread() {
81113d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  return sizeof(Relocatable*);  // NOLINT
8112c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
8113c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
8114c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
8115fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org// Archive statics that are thread-local.
81161c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.orgchar* Relocatable::ArchiveState(Isolate* isolate, char* to) {
8117ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  *reinterpret_cast<Relocatable**>(to) = isolate->relocatable_top();
8118ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->set_relocatable_top(NULL);
8119c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  return to + ArchiveSpacePerThread();
8120c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
8121c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
8122c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
8123fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org// Restore statics that are thread-local.
81241c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.orgchar* Relocatable::RestoreState(Isolate* isolate, char* from) {
8125ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate->set_relocatable_top(*reinterpret_cast<Relocatable**>(from));
8126c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  return from + ArchiveSpacePerThread();
8127c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
8128c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
8129c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
8130c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgchar* Relocatable::Iterate(ObjectVisitor* v, char* thread_storage) {
8131c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  Relocatable* top = *reinterpret_cast<Relocatable**>(thread_storage);
8132c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  Iterate(v, top);
8133c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  return thread_storage + ArchiveSpacePerThread();
8134c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
8135c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
8136c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
81373d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid Relocatable::Iterate(Isolate* isolate, ObjectVisitor* v) {
8138ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Iterate(v, isolate->relocatable_top());
8139c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
8140c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
8141c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
8142c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgvoid Relocatable::Iterate(ObjectVisitor* v, Relocatable* top) {
8143c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  Relocatable* current = top;
8144c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  while (current != NULL) {
8145c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    current->IterateInstance(v);
8146c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    current = current->prev_;
8147c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  }
8148c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
8149a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
8150a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
8151ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgFlatStringReader::FlatStringReader(Isolate* isolate, Handle<String> str)
8152ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    : Relocatable(isolate),
8153ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      str_(str.location()),
8154c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org      length_(str->length()) {
8155c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  PostGarbageCollection();
8156a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
8157a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
8158a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
8159ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgFlatStringReader::FlatStringReader(Isolate* isolate, Vector<const char> input)
8160ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    : Relocatable(isolate),
8161ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      str_(0),
81622c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      is_one_byte_(true),
8163a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      length_(input.length()),
81642c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      start_(input.start()) {}
8165a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
8166a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
8167c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgvoid FlatStringReader::PostGarbageCollection() {
8168a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (str_ == NULL) return;
8169a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Handle<String> str(str_);
8170e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(str->IsFlat());
817179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
8172a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  // This does not actually prevent the vector from being relocated later.
8173ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent content = str->GetFlatContent();
8174e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(content.IsFlat());
81752c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  is_one_byte_ = content.IsOneByte();
81762c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  if (is_one_byte_) {
817759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    start_ = content.ToOneByteVector().start();
8178a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  } else {
8179ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    start_ = content.ToUC16Vector().start();
8180a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
8181a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
8182a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
8183a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
81843484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgvoid ConsStringIteratorOp::Initialize(ConsString* cons_string, int offset) {
8185e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(cons_string != NULL);
8186a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  root_ = cons_string;
81873484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  consumed_ = offset;
81883484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  // Force stack blown condition to trigger restart.
81893484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  depth_ = 1;
81903484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  maximum_depth_ = kStackSize + depth_;
8191e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(StackBlown());
8192a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
8193a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
8194a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
81953484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgString* ConsStringIteratorOp::Continue(int* offset_out) {
8196e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(depth_ != 0);
8197e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(0, *offset_out);
81983484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  bool blew_stack = StackBlown();
81993484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  String* string = NULL;
82003484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  // Get the next leaf if there is one.
82013484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  if (!blew_stack) string = NextLeaf(&blew_stack);
82023484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  // Restart search from root.
82033484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  if (blew_stack) {
8204e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(string == NULL);
82053484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    string = Search(offset_out);
82063484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  }
82073484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  // Ensure future calls return null immediately.
82083484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  if (string == NULL) Reset(NULL);
82093484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  return string;
82103484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org}
82113484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org
82123484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org
82133484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgString* ConsStringIteratorOp::Search(int* offset_out) {
8214a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ConsString* cons_string = root_;
8215a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Reset the stack, pushing the root string.
8216a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  depth_ = 1;
8217a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  maximum_depth_ = 1;
8218a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  frames_[0] = cons_string;
82193484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  const int consumed = consumed_;
82203484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  int offset = 0;
822132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  while (true) {
822232280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    // Loop until the string is found which contains the target offset.
8223a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    String* string = cons_string->first();
82243484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    int length = string->length();
822532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    int32_t type;
8226a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (consumed < offset + length) {
822732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      // Target offset is in the left branch.
822832280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      // Keep going if we're still in a ConString.
822932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      type = string->map()->instance_type();
823032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      if ((type & kStringRepresentationMask) == kConsStringTag) {
8231a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        cons_string = ConsString::cast(string);
8232a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        PushLeft(cons_string);
823332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org        continue;
823432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      }
82353484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      // Tell the stack we're done descending.
8236a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      AdjustMaximumDepth();
823732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    } else {
823832280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      // Descend right.
823932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      // Update progress through the string.
824032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      offset += length;
824132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      // Keep going if we're still in a ConString.
8242a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      string = cons_string->second();
824332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      type = string->map()->instance_type();
824432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      if ((type & kStringRepresentationMask) == kConsStringTag) {
8245a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        cons_string = ConsString::cast(string);
8246a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        PushRight(cons_string);
824732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org        continue;
824832280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      }
824932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      // Need this to be updated for the current string.
825032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      length = string->length();
825132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      // Account for the possibility of an empty right leaf.
8252a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      // This happens only if we have asked for an offset outside the string.
8253a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      if (length == 0) {
82543484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org        // Reset so future operations will return null immediately.
82553484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org        Reset(NULL);
8256a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        return NULL;
8257a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      }
82583484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      // Tell the stack we're done descending.
8259a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      AdjustMaximumDepth();
8260a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      // Pop stack so next iteration is in correct place.
8261a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      Pop();
826232280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    }
8263e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(length != 0);
826432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    // Adjust return values and exit.
8265a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    consumed_ = offset + length;
8266a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    *offset_out = consumed - offset;
826732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    return string;
826832280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  }
826932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  UNREACHABLE();
827032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  return NULL;
827132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org}
827232280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
827332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
82743484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgString* ConsStringIteratorOp::NextLeaf(bool* blew_stack) {
827532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  while (true) {
827632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    // Tree traversal complete.
827732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    if (depth_ == 0) {
8278a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      *blew_stack = false;
827932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      return NULL;
828032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    }
828132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    // We've lost track of higher nodes.
82823484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    if (StackBlown()) {
8283a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      *blew_stack = true;
828432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      return NULL;
828532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    }
828632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    // Go right.
8287a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ConsString* cons_string = frames_[OffsetForDepth(depth_ - 1)];
8288a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    String* string = cons_string->second();
828932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    int32_t type = string->map()->instance_type();
829032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    if ((type & kStringRepresentationMask) != kConsStringTag) {
829132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      // Pop stack so next iteration is in correct place.
829232280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      Pop();
82933484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      int length = string->length();
8294a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      // Could be a flattened ConsString.
8295a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      if (length == 0) continue;
8296a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      consumed_ += length;
829732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      return string;
829832280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    }
8299a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    cons_string = ConsString::cast(string);
8300a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    PushRight(cons_string);
830132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    // Need to traverse all the way left.
830232280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    while (true) {
830332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      // Continue left.
8304a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      string = cons_string->first();
830532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      type = string->map()->instance_type();
830632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      if ((type & kStringRepresentationMask) != kConsStringTag) {
830732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org        AdjustMaximumDepth();
83083484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org        int length = string->length();
8309e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(length != 0);
8310a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        consumed_ += length;
831132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org        return string;
831232280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org      }
8313a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      cons_string = ConsString::cast(string);
8314a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      PushLeft(cons_string);
831532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    }
831632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  }
831732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  UNREACHABLE();
831832280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  return NULL;
831943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
832043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
832143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
832243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenuint16_t ConsString::ConsStringGet(int index) {
8323e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index >= 0 && index < this->length());
832443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
832543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check for a flattened cons string
8326870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  if (second()->length() == 0) {
8327870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    String* left = first();
8328bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    return left->Get(index);
832943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
833043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
833143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  String* string = String::cast(this);
833243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
833343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (true) {
8334bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    if (StringShape(string).IsCons()) {
833543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      ConsString* cons_string = ConsString::cast(string);
8336870a0b67c822d289024711912e2512af01b66c3bager@chromium.org      String* left = cons_string->first();
8337bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      if (left->length() > index) {
833843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        string = left;
833943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
8340bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        index -= left->length();
8341870a0b67c822d289024711912e2512af01b66c3bager@chromium.org        string = cons_string->second();
834243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
834343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
8344bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      return string->Get(index);
834543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
834643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
834743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
834843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  UNREACHABLE();
834943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return 0;
835043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
835143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
835243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
83534668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.orguint16_t SlicedString::SlicedStringGet(int index) {
83544668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  return parent()->Get(offset() + index);
83554668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org}
83564668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org
83574668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org
83585a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgtemplate <typename sinkchar>
83595a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgvoid String::WriteToFlat(String* src,
83605a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                         sinkchar* sink,
83615a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                         int f,
83625a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                         int t) {
836343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  String* source = src;
836443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int from = f;
836543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int to = t;
836643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (true) {
8367e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(0 <= from && from <= to && to <= source->length());
8368bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    switch (StringShape(source).full_representation_tag()) {
8369e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case kOneByteStringTag | kExternalStringTag: {
83702c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        CopyChars(sink, ExternalOneByteString::cast(source)->GetChars() + from,
83715a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                  to - from);
837243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        return;
837343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
83745a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      case kTwoByteStringTag | kExternalStringTag: {
83755a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org        const uc16* data =
83760ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry            ExternalTwoByteString::cast(source)->GetChars();
83775a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org        CopyChars(sink,
83785a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                  data + from,
83795a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                  to - from);
83805a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org        return;
83815a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      }
8382e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case kOneByteStringTag | kSeqStringTag: {
83835a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org        CopyChars(sink,
8384fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                  SeqOneByteString::cast(source)->GetChars() + from,
83855a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                  to - from);
83865a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org        return;
83875a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      }
83885a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      case kTwoByteStringTag | kSeqStringTag: {
83895a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org        CopyChars(sink,
83905a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                  SeqTwoByteString::cast(source)->GetChars() + from,
83915a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                  to - from);
83925a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org        return;
83935a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      }
8394e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case kOneByteStringTag | kConsStringTag:
83955a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org      case kTwoByteStringTag | kConsStringTag: {
839643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        ConsString* cons_string = ConsString::cast(source);
8397870a0b67c822d289024711912e2512af01b66c3bager@chromium.org        String* first = cons_string->first();
8398bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        int boundary = first->length();
83997c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org        if (to - boundary >= boundary - from) {
840043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          // Right hand side is longer.  Recurse over left.
840143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          if (from < boundary) {
8402bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org            WriteToFlat(first, sink, from, boundary);
84035a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org            sink += boundary - from;
840443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            from = 0;
840543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          } else {
840643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            from -= boundary;
840743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          }
840843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          to -= boundary;
8409870a0b67c822d289024711912e2512af01b66c3bager@chromium.org          source = cons_string->second();
841043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        } else {
84115a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org          // Left hand side is longer.  Recurse over right.
841243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          if (to > boundary) {
8413870a0b67c822d289024711912e2512af01b66c3bager@chromium.org            String* second = cons_string->second();
8414812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org            // When repeatedly appending to a string, we get a cons string that
8415812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org            // is unbalanced to the left, a list, essentially.  We inline the
84162c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org            // common case of sequential one-byte right child.
8417812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org            if (to - boundary == 1) {
8418812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org              sink[boundary - from] = static_cast<sinkchar>(second->Get(0));
8419fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            } else if (second->IsSeqOneByteString()) {
8420812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org              CopyChars(sink + boundary - from,
8421fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                        SeqOneByteString::cast(second)->GetChars(),
84225a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                        to - boundary);
8423812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org            } else {
8424812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org              WriteToFlat(second,
8425812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org                          sink + boundary - from,
8426812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org                          0,
8427812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org                          to - boundary);
8428812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org            }
842943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen            to = boundary;
843043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          }
843143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          source = first;
843243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
84335a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org        break;
843443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
8435e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      case kOneByteStringTag | kSlicedStringTag:
84364668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      case kTwoByteStringTag | kSlicedStringTag: {
84374668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org        SlicedString* slice = SlicedString::cast(source);
84384668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org        unsigned offset = slice->offset();
84394668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org        WriteToFlat(slice->parent(), sink, from + offset, to + offset);
84404668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org        return;
84414668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org      }
844243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
844343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
844443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
844543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
844643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
84479fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
84489fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgtemplate <typename SourceChar>
84499fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgstatic void CalculateLineEndsImpl(Isolate* isolate,
84509fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                  List<int>* line_ends,
84519fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                  Vector<const SourceChar> src,
84529fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                  bool include_ending_line) {
84539fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  const int src_len = src.length();
84542c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  StringSearch<uint8_t, SourceChar> search(isolate, STATIC_CHAR_VECTOR("\n"));
84559fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
84569fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Find and record line ends.
84579fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int position = 0;
84589fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  while (position != -1 && position < src_len) {
84599fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    position = search.Search(src, position);
84609fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (position != -1) {
84619fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      line_ends->Add(position);
84629fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      position++;
84639fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    } else if (include_ending_line) {
84649fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      // Even if the last line misses a line end, it is counted.
84659fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      line_ends->Add(src_len);
84669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      return;
84679fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
84689fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
84699fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
84709fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
84719fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
84729fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgHandle<FixedArray> String::CalculateLineEnds(Handle<String> src,
84739fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                             bool include_ending_line) {
84749fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  src = Flatten(src);
84759fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Rough estimate of line count based on a roughly estimated average
84769fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // length of (unpacked) code.
84779fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int line_count_estimate = src->length() >> 4;
84789fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  List<int> line_ends(line_count_estimate);
84799fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Isolate* isolate = src->GetIsolate();
84809fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  { DisallowHeapAllocation no_allocation;  // ensure vectors stay valid.
84819fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // Dispatch on type of strings.
84829fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    String::FlatContent content = src->GetFlatContent();
8483e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(content.IsFlat());
84842c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    if (content.IsOneByte()) {
84859fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      CalculateLineEndsImpl(isolate,
84869fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                            &line_ends,
84879fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                            content.ToOneByteVector(),
84889fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                            include_ending_line);
84899fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    } else {
84909fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      CalculateLineEndsImpl(isolate,
84919fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                            &line_ends,
84929fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                            content.ToUC16Vector(),
84939fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                            include_ending_line);
84949fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
84959fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
84969fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int line_count = line_ends.length();
84979fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<FixedArray> array = isolate->factory()->NewFixedArray(line_count);
84989fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  for (int i = 0; i < line_count; i++) {
84999fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    array->set(i, Smi::FromInt(line_ends[i]));
85009fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
85019fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return array;
85029fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
85039fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
85049fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
85055a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// Compares the contents of two strings by reading and comparing
85065a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// int-sized blocks of characters.
85075a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgtemplate <typename Char>
85084cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgstatic inline bool CompareRawStringContents(const Char* const a,
85094cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org                                            const Char* const b,
85104cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org                                            int length) {
85119e2b466e4b4a2026caefa79afe6737f1bad83a19machenbach@chromium.org  return CompareChars(a, b, length) == 0;
85125a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}
85135a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
85145a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
85154cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgtemplate<typename Chars1, typename Chars2>
85164cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgclass RawStringComparator : public AllStatic {
85174cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org public:
85184cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static inline bool compare(const Chars1* a, const Chars2* b, int len) {
8519e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(sizeof(Chars1) != sizeof(Chars2));
85204cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    for (int i = 0; i < len; i++) {
85214cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      if (a[i] != b[i]) {
85224cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        return false;
85234cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      }
85247c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    }
85254cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    return true;
85267c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  }
85274cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org};
85284cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
85294cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
85304cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgtemplate<>
85314cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgclass RawStringComparator<uint16_t, uint16_t> {
85324cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org public:
85334cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static inline bool compare(const uint16_t* a, const uint16_t* b, int len) {
85344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    return CompareRawStringContents(a, b, len);
85354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
85364cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org};
85374cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
85384cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
85394cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgtemplate<>
85404cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgclass RawStringComparator<uint8_t, uint8_t> {
85414cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org public:
85424cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  static inline bool compare(const uint8_t* a, const uint8_t* b, int len) {
85434cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    return CompareRawStringContents(a, b, len);
85444cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
85454cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org};
85464cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
85474cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
85484cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgclass StringComparator {
85494cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  class State {
85504cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org   public:
85514cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    explicit inline State(ConsStringIteratorOp* op)
85524cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      : op_(op), is_one_byte_(true), length_(0), buffer8_(NULL) {}
85534cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
85543484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    inline void Init(String* string) {
85553484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      ConsString* cons_string = String::VisitFlat(this, string);
85563484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      op_->Reset(cons_string);
85573484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      if (cons_string != NULL) {
85583484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org        int offset;
85593484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org        string = op_->Next(&offset);
85603484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org        String::VisitFlat(this, string, offset);
85613484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      }
85624cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    }
85634cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
85643484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    inline void VisitOneByteString(const uint8_t* chars, int length) {
85654cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      is_one_byte_ = true;
85664cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      buffer8_ = chars;
85674cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      length_ = length;
85684cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    }
85694cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
85703484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    inline void VisitTwoByteString(const uint16_t* chars, int length) {
85714cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      is_one_byte_ = false;
85724cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      buffer16_ = chars;
85734cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      length_ = length;
85744cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    }
85754cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
85763484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    void Advance(int consumed) {
8577e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(consumed <= length_);
85784cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      // Still in buffer.
85794cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      if (length_ != consumed) {
85804cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        if (is_one_byte_) {
85814cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org          buffer8_ += consumed;
85824cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        } else {
85834cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org          buffer16_ += consumed;
85844cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        }
85854cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        length_ -= consumed;
85864cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        return;
85874cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      }
85884cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      // Advance state.
85893484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      int offset;
85903484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      String* next = op_->Next(&offset);
8591e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK_EQ(0, offset);
8592e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(next != NULL);
85933484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      String::VisitFlat(this, next);
85944cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    }
85954cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
85964cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    ConsStringIteratorOp* const op_;
85974cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    bool is_one_byte_;
85983484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    int length_;
85994cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    union {
86004cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      const uint8_t* buffer8_;
86014cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      const uint16_t* buffer16_;
86024cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    };
86031fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
86041fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org   private:
86054cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    DISALLOW_IMPLICIT_CONSTRUCTORS(State);
86064cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  };
86074cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
86084cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org public:
86094cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  inline StringComparator(ConsStringIteratorOp* op_1,
86104cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org                          ConsStringIteratorOp* op_2)
86114cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    : state_1_(op_1),
86124cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      state_2_(op_2) {
86134cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
86144cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
86154cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  template<typename Chars1, typename Chars2>
86163484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  static inline bool Equals(State* state_1, State* state_2, int to_check) {
86174cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    const Chars1* a = reinterpret_cast<const Chars1*>(state_1->buffer8_);
86184cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    const Chars2* b = reinterpret_cast<const Chars2*>(state_2->buffer8_);
86194cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    return RawStringComparator<Chars1, Chars2>::compare(a, b, to_check);
86204cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
86214cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
86223484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  bool Equals(String* string_1, String* string_2) {
86233484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    int length = string_1->length();
86243484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    state_1_.Init(string_1);
86253484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    state_2_.Init(string_2);
86264cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    while (true) {
86273484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      int to_check = Min(state_1_.length_, state_2_.length_);
8628e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(to_check > 0 && to_check <= length);
86294cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      bool is_equal;
86304cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      if (state_1_.is_one_byte_) {
86314cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        if (state_2_.is_one_byte_) {
86324cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org          is_equal = Equals<uint8_t, uint8_t>(&state_1_, &state_2_, to_check);
86334cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        } else {
86344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org          is_equal = Equals<uint8_t, uint16_t>(&state_1_, &state_2_, to_check);
86354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        }
86364cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      } else {
86374cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        if (state_2_.is_one_byte_) {
86384cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org          is_equal = Equals<uint16_t, uint8_t>(&state_1_, &state_2_, to_check);
86394cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        } else {
86404cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org          is_equal = Equals<uint16_t, uint16_t>(&state_1_, &state_2_, to_check);
86414cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org        }
86424cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      }
86434cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      // Looping done.
86444cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      if (!is_equal) return false;
86454cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      length -= to_check;
86464cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      // Exit condition. Strings are equal.
86474cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      if (length == 0) return true;
86484cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      state_1_.Advance(to_check);
86494cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org      state_2_.Advance(to_check);
86504cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    }
86514cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }
86524cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
86534cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org private:
86544cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  State state_1_;
86554cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  State state_2_;
86564cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  DISALLOW_IMPLICIT_CONSTRUCTORS(StringComparator);
86574cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org};
86587c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
86597c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
8660bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgbool String::SlowEquals(String* other) {
86612ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  DisallowHeapAllocation no_gc;
866243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fast check: negative check with lengths.
8663bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int len = length();
8664bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (len != other->length()) return false;
866543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (len == 0) return true;
866643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
866743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fast check: if hash code is computed for both strings
866843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // a fast negative check can be performed.
866943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (HasHashCode() && other->HasHashCode()) {
8670e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org#ifdef ENABLE_SLOW_DCHECKS
8671fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    if (FLAG_enable_slow_asserts) {
8672fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org      if (Hash() != other->Hash()) {
8673fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org        bool found_difference = false;
8674fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org        for (int i = 0; i < len; i++) {
8675fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org          if (Get(i) != other->Get(i)) {
8676fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org            found_difference = true;
8677fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org            break;
8678fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org          }
8679fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org        }
8680e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(found_difference);
8681fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org      }
8682fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    }
8683fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org#endif
868443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (Hash() != other->Hash()) return false;
868543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
868643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86879dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  // We know the strings are both non-empty. Compare the first chars
86889dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  // before we try to flatten the strings.
86899dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  if (this->Get(0) != other->Get(0)) return false;
86909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
86912ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (IsSeqOneByteString() && other->IsSeqOneByteString()) {
86922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    const uint8_t* str1 = SeqOneByteString::cast(this)->GetChars();
86932ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    const uint8_t* str2 = SeqOneByteString::cast(other)->GetChars();
86944cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    return CompareRawStringContents(str1, str2, len);
86955a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
86965a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
8697ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate = GetIsolate();
86984cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  StringComparator comparator(isolate->objects_string_compare_iterator_a(),
86994cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org                              isolate->objects_string_compare_iterator_b());
87004cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
87013484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  return comparator.Equals(this, other);
87022ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org}
87032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
87042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
87052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgbool String::SlowEquals(Handle<String> one, Handle<String> two) {
87062ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Fast check: negative check with lengths.
87072ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int one_length = one->length();
87082ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (one_length != two->length()) return false;
87092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (one_length == 0) return true;
87102ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
87112ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Fast check: if hash code is computed for both strings
87122ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // a fast negative check can be performed.
87132ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (one->HasHashCode() && two->HasHashCode()) {
8714e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org#ifdef ENABLE_SLOW_DCHECKS
87152ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (FLAG_enable_slow_asserts) {
87162ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      if (one->Hash() != two->Hash()) {
87172ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        bool found_difference = false;
87182ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        for (int i = 0; i < one_length; i++) {
87192ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          if (one->Get(i) != two->Get(i)) {
87202ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org            found_difference = true;
87212ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org            break;
87222ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          }
87232ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        }
8724e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(found_difference);
87252ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      }
87262ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    }
87272ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org#endif
87282ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (one->Hash() != two->Hash()) return false;
87292ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
87302ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
87312ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // We know the strings are both non-empty. Compare the first chars
87322ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // before we try to flatten the strings.
87332ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (one->Get(0) != two->Get(0)) return false;
87342ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
87352ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  one = String::Flatten(one);
87362ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  two = String::Flatten(two);
87372ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
87382ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  DisallowHeapAllocation no_gc;
87392ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  String::FlatContent flat1 = one->GetFlatContent();
87402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  String::FlatContent flat2 = two->GetFlatContent();
87412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
87422c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  if (flat1.IsOneByte() && flat2.IsOneByte()) {
87432ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      return CompareRawStringContents(flat1.ToOneByteVector().start(),
87442ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                      flat2.ToOneByteVector().start(),
87452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                      one_length);
87462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  } else {
87472ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    for (int i = 0; i < one_length; i++) {
87482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      if (flat1.Get(i) != flat2.Get(i)) return false;
87492ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    }
87502ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    return true;
87512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
875243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
875343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
875443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
875543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool String::MarkAsUndetectable() {
87564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (StringShape(this).IsInternalized()) return false;
875743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
875843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Map* map = this->map();
8759c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Heap* heap = GetHeap();
8760ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (map == heap->string_map()) {
8761ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    this->set_map(heap->undetectable_string_map());
876243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return true;
87632c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  } else if (map == heap->one_byte_string_map()) {
87642c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    this->set_map(heap->undetectable_one_byte_string_map());
876543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return true;
876643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
876743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Rest cannot be marked as undetectable
876843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return false;
876943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
877043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
877143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8772906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.orgbool String::IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match) {
8773bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int slen = length();
8774a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Can't check exact length equality, but we can check bounds.
8775a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  int str_len = str.length();
8776906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  if (!allow_prefix_match &&
8777906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      (str_len < slen ||
8778906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org          str_len > slen*static_cast<int>(unibrow::Utf8::kMaxEncodedSize))) {
8779a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return false;
8780a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
878143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int i;
8782a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  unsigned remaining_in_str = static_cast<unsigned>(str_len);
8783a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  const uint8_t* utf8_data = reinterpret_cast<const uint8_t*>(str.start());
8784a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  for (i = 0; i < slen && remaining_in_str > 0; i++) {
8785a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    unsigned cursor = 0;
8786a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    uint32_t r = unibrow::Utf8::ValueOf(utf8_data, remaining_in_str, &cursor);
8787e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(cursor > 0 && cursor <= remaining_in_str);
8788154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    if (r > unibrow::Utf16::kMaxNonSurrogateCharCode) {
8789154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      if (i > slen - 1) return false;
8790154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      if (Get(i++) != unibrow::Utf16::LeadSurrogate(r)) return false;
8791154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      if (Get(i) != unibrow::Utf16::TrailSurrogate(r)) return false;
8792154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    } else {
8793154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      if (Get(i) != r) return false;
8794154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    }
8795a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    utf8_data += cursor;
8796a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    remaining_in_str -= cursor;
879743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
8798906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  return (allow_prefix_match || i == slen) && remaining_in_str == 0;
879943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
880043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
880143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
880259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgbool String::IsOneByteEqualTo(Vector<const uint8_t> str) {
88039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  int slen = length();
88049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  if (str.length() != slen) return false;
880579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
8806ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  FlatContent content = GetFlatContent();
88072c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  if (content.IsOneByte()) {
880859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return CompareChars(content.ToOneByteVector().start(),
8809ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org                        str.start(), slen) == 0;
8810c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  }
8811c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  for (int i = 0; i < slen; i++) {
8812c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org    if (Get(i) != static_cast<uint16_t>(str[i])) return false;
88139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  }
88149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  return true;
88159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
88169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
88179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
88189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgbool String::IsTwoByteEqualTo(Vector<const uc16> str) {
88199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  int slen = length();
88209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  if (str.length() != slen) return false;
882179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
8822ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  FlatContent content = GetFlatContent();
8823ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  if (content.IsTwoByte()) {
8824ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    return CompareChars(content.ToUC16Vector().start(), str.start(), slen) == 0;
8825c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  }
88269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  for (int i = 0; i < slen; i++) {
88279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    if (Get(i) != str[i]) return false;
88289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  }
88299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  return true;
88309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
88319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
88329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
883343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenuint32_t String::ComputeAndSetHash() {
88343b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org  // Should only be called if hash code has not yet been computed.
8835e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!HasHashCode());
883643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
883743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Store the hash code in the object.
8838a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  uint32_t field = IteratingStringHasher::Hash(this, GetHeap()->HashSeed());
8839ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  set_hash_field(field);
884043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
884143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check the hash code is there.
8842e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(HasHashCode());
88433b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org  uint32_t result = field >> kHashShift;
8844e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(result != 0);  // Ensure that the hash value of 0 is never computed.
88453b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org  return result;
884643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
884743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
884843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88494cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgbool String::ComputeArrayIndex(uint32_t* index) {
88504cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  int length = this->length();
88515a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  if (length == 0 || length > kMaxArrayIndexSize) return false;
88524cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ConsStringIteratorOp op;
88534cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  StringCharacterStream stream(this, &op);
885408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  return StringToArrayIndex(&stream, index);
885543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
885643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
885743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
885843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool String::SlowAsArrayIndex(uint32_t* index) {
8859bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  if (length() <= kMaxCachedArrayIndexLength) {
88605a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    Hash();  // force computation of hash code
8861ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org    uint32_t field = hash_field();
88621af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org    if ((field & kIsNotArrayIndexMask) != 0) return false;
8863ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org    // Isolate the array index form the full hash field.
8864d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    *index = ArrayIndexValueBits::decode(field);
88655a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    return true;
88665a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  } else {
88674cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    return ComputeArrayIndex(index);
88685a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
886943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
887043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
887143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8872f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgHandle<String> SeqString::Truncate(Handle<SeqString> string, int new_length) {
8873f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  int new_size, old_size;
8874f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  int old_length = string->length();
8875f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (old_length <= new_length) return string;
887632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
8877f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (string->IsSeqOneByteString()) {
8878f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    old_size = SeqOneByteString::SizeFor(old_length);
8879f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    new_size = SeqOneByteString::SizeFor(new_length);
888032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  } else {
8881e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(string->IsSeqTwoByteString());
8882f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    old_size = SeqTwoByteString::SizeFor(old_length);
8883f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    new_size = SeqTwoByteString::SizeFor(new_length);
888432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  }
888532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
8886f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  int delta = old_size - new_size;
888732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
8888f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Address start_of_string = string->address();
8889e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_OBJECT_ALIGNED(start_of_string);
8890e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_OBJECT_ALIGNED(start_of_string + new_size);
8891f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
8892f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Heap* heap = string->GetHeap();
8893f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  NewSpace* newspace = heap->new_space();
8894f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (newspace->Contains(start_of_string) &&
8895f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      newspace->top() == start_of_string + old_size) {
8896f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    // Last allocated object in new space.  Simply lower allocation top.
8897ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    newspace->set_top(start_of_string + new_size);
8898f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  } else {
8899f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    // Sizes are pointer size aligned, so that we can use filler objects
8900f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    // that are a multiple of pointer size.
8901f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    heap->CreateFillerObjectAt(start_of_string + new_size, delta);
890232280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  }
89035697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  heap->AdjustLiveBytes(start_of_string, -delta, Heap::FROM_MUTATOR);
8904f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
890563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  // We are storing the new length using release store after creating a filler
890663a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  // for the left-over space to avoid races with the sweeper thread.
890763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  string->synchronized_set_length(new_length);
890863a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org
8909f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  if (new_length == 0) return heap->isolate()->factory()->empty_string();
8910f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  return string;
891132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org}
891232280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
891332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
89145b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.orguint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
8915d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // For array indexes mix the length into the hash as an array index could
8916d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // be zero.
8917e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(length > 0);
8918e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(length <= String::kMaxArrayIndexSize);
8919e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(TenToThe(String::kMaxCachedArrayIndexLength) <
8920d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org         (1 << String::kArrayIndexValueBits));
89215b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
8922d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  value <<= String::ArrayIndexValueBits::kShift;
8923d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  value |= length << String::ArrayIndexLengthBits::kShift;
89245b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
8925e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((value & String::kIsNotArrayIndexMask) == 0);
8926e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((length > String::kMaxCachedArrayIndexLength) ||
89275b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org         (value & String::kContainsCachedArrayIndexMask) == 0);
8928d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  return value;
892943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
893043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
893143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
89327c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.orguint32_t StringHasher::GetHashField() {
8933ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  if (length_ <= String::kMaxHashCalcLength) {
8934a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (is_array_index_) {
8935a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      return MakeArrayIndexHash(array_index_, length_);
89367c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org    }
8937a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return (GetHashCore(raw_running_hash_) << String::kHashShift) |
8938a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org           String::kIsNotArrayIndexMask;
89397c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  } else {
8940d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    return (length_ << String::kHashShift) | String::kIsNotArrayIndexMask;
894143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
89427c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org}
89437c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
89447c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
8945a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orguint32_t StringHasher::ComputeUtf8Hash(Vector<const char> chars,
8946a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                       uint32_t seed,
8947a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                       int* utf16_length_out) {
8948a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  int vector_length = chars.length();
8949a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Handle some edge cases
8950a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (vector_length <= 1) {
8951e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(vector_length == 0 ||
8952a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org           static_cast<uint8_t>(chars.start()[0]) <=
8953a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org               unibrow::Utf8::kMaxOneByteChar);
8954a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    *utf16_length_out = vector_length;
8955a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return HashSequentialString(chars.start(), vector_length, seed);
8956a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
8957a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Start with a fake length which won't affect computation.
8958a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // It will be updated later.
8959a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  StringHasher hasher(String::kMaxArrayIndexSize, seed);
8960a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  unsigned remaining = static_cast<unsigned>(vector_length);
8961a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  const uint8_t* stream = reinterpret_cast<const uint8_t*>(chars.start());
8962a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  int utf16_length = 0;
8963a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool is_index = true;
8964e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(hasher.is_array_index_);
8965a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  while (remaining > 0) {
8966a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    unsigned consumed = 0;
8967a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    uint32_t c = unibrow::Utf8::ValueOf(stream, remaining, &consumed);
8968e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(consumed > 0 && consumed <= remaining);
8969a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    stream += consumed;
8970a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    remaining -= consumed;
8971a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    bool is_two_characters = c > unibrow::Utf16::kMaxNonSurrogateCharCode;
8972a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    utf16_length += is_two_characters ? 2 : 1;
8973a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    // No need to keep hashing. But we do need to calculate utf16_length.
8974a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (utf16_length > String::kMaxHashCalcLength) continue;
8975a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (is_two_characters) {
8976a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      uint16_t c1 = unibrow::Utf16::LeadSurrogate(c);
8977a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      uint16_t c2 = unibrow::Utf16::TrailSurrogate(c);
8978a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      hasher.AddCharacter(c1);
8979a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      hasher.AddCharacter(c2);
8980a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      if (is_index) is_index = hasher.UpdateIndex(c1);
8981a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      if (is_index) is_index = hasher.UpdateIndex(c2);
8982a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    } else {
8983a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      hasher.AddCharacter(c);
8984a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      if (is_index) is_index = hasher.UpdateIndex(c);
8985a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
89865a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
8987a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  *utf16_length_out = static_cast<int>(utf16_length);
8988a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Must set length here so that hash computation is correct.
8989a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  hasher.length_ = utf16_length;
89907c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  return hasher.GetHashField();
899143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
899243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
899343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
899443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid String::PrintOn(FILE* file) {
8995bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  int length = this->length();
899643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < length; i++) {
8997e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    PrintF(file, "%c", Get(i));
899843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
899943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
900043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
900143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9002e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgint Map::Hash() {
9003e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // For performance reasons we only hash the 3 most variable fields of a map:
9004e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // constructor, prototype and bit_field2.
9005e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
9006e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // Shift away the tag.
9007e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  int hash = (static_cast<uint32_t>(
9008e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org        reinterpret_cast<uintptr_t>(constructor())) >> 2);
9009e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
9010e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // XOR-ing the prototype and constructor directly yields too many zero bits
9011e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // when the two pointers are close (which is fairly common).
9012e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  // To avoid this we shift the prototype 4 bits relatively to the constructor.
9013e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  hash ^= (static_cast<uint32_t>(
9014e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org        reinterpret_cast<uintptr_t>(prototype())) << 2);
9015e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
9016e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  return hash ^ (hash >> 16) ^ bit_field2();
9017e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org}
9018e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
9019e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
9020f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgstatic bool CheckEquivalent(Map* first, Map* second) {
9021f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  return
9022f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    first->constructor() == second->constructor() &&
9023f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    first->prototype() == second->prototype() &&
9024f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    first->instance_type() == second->instance_type() &&
9025f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    first->bit_field() == second->bit_field() &&
9026f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    first->bit_field2() == second->bit_field2() &&
90273c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    first->is_frozen() == second->is_frozen() &&
90283c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    first->has_instance_call_handler() == second->has_instance_call_handler();
9029f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
9030f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
9031f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
9032f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgbool Map::EquivalentToForTransition(Map* other) {
9033f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  return CheckEquivalent(this, other);
9034f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
9035f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
9036f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
9037e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgbool Map::EquivalentToForNormalization(Map* other,
9038e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org                                       PropertyNormalizationMode mode) {
9039f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  int properties = mode == CLEAR_INOBJECT_PROPERTIES
9040f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      ? 0 : other->inobject_properties();
9041f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  return CheckEquivalent(this, other) && inobject_properties() == properties;
9042e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org}
9043e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
9044e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
9045a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.orgvoid ConstantPoolArray::ConstantPoolIterateBody(ObjectVisitor* v) {
9046d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Unfortunately the serializer relies on pointers within an object being
9047d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // visited in-order, so we have to iterate both the code and heap pointers in
9048d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // the small section before doing so in the extended section.
9049d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  for (int s = 0; s <= final_section(); ++s) {
9050d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    LayoutSection section = static_cast<LayoutSection>(s);
9051d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    ConstantPoolArray::Iterator code_iter(this, ConstantPoolArray::CODE_PTR,
9052d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org                                          section);
9053d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    while (!code_iter.is_finished()) {
9054d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      v->VisitCodeEntry(reinterpret_cast<Address>(
9055d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org          RawFieldOfElementAt(code_iter.next_index())));
9056d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    }
90575d6930502bea0aeb6fdbc4cf04cf87c908ce0127machenbach@chromium.org
9058d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    ConstantPoolArray::Iterator heap_iter(this, ConstantPoolArray::HEAP_PTR,
9059d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org                                          section);
9060d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    while (!heap_iter.is_finished()) {
9061d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      v->VisitPointer(RawFieldOfElementAt(heap_iter.next_index()));
9062d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    }
9063196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  }
9064196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
9065196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
9066196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
9067196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgvoid ConstantPoolArray::ClearPtrEntries(Isolate* isolate) {
9068196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  Type type[] = { CODE_PTR, HEAP_PTR };
9069196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  Address default_value[] = {
9070196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        isolate->builtins()->builtin(Builtins::kIllegal)->entry(),
9071196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        reinterpret_cast<Address>(isolate->heap()->undefined_value()) };
9072196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
9073196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  for (int i = 0; i < 2; ++i) {
9074196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    for (int s = 0; s <= final_section(); ++s) {
9075196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      LayoutSection section = static_cast<LayoutSection>(s);
9076196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      if (number_of_entries(type[i], section) > 0) {
9077196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        int offset = OffsetOfElementAt(first_index(type[i], section));
9078196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        MemsetPointer(
9079196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          reinterpret_cast<Address*>(HeapObject::RawField(this, offset)),
9080196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          default_value[i],
9081196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          number_of_entries(type[i], section));
9082196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      }
9083196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    }
90849ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  }
9085a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org}
9086a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
9087a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
9088145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.comvoid JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) {
9089145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  // Iterate over all fields in the body but take care in dealing with
9090145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  // the code entry.
9091145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  IteratePointers(v, kPropertiesOffset, kCodeEntryOffset);
9092145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  v->VisitCodeEntry(this->address() + kCodeEntryOffset);
9093145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size);
9094145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com}
9095145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com
9096145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com
90974954674151afa960af66efb4831df06bde727333yangguo@chromium.orgvoid JSFunction::MarkForOptimization() {
9098e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsOptimized());
9099e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(shared()->allows_lazy_compilation() ||
9100c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org         code()->optimizable());
9101e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!shared()->is_generator());
91026e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  set_code_no_write_barrier(
91034954674151afa960af66efb4831df06bde727333yangguo@chromium.org      GetIsolate()->builtins()->builtin(Builtins::kCompileOptimized));
91046e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // No write barrier required, since the builtin is part of the root set.
9105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
9106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
91076e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
91084954674151afa960af66efb4831df06bde727333yangguo@chromium.orgvoid JSFunction::MarkForConcurrentOptimization() {
9109e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_compiled() || GetIsolate()->DebuggerHasBreakPoints());
9110e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsOptimized());
9111e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(shared()->allows_lazy_compilation() || code()->optimizable());
9112e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!shared()->is_generator());
9113e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(GetIsolate()->concurrent_recompilation_enabled());
91149259716434187c932704601f700375e53d865de8rossberg@chromium.org  if (FLAG_trace_concurrent_recompilation) {
91156e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    PrintF("  ** Marking ");
9116b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org    ShortPrint();
91179259716434187c932704601f700375e53d865de8rossberg@chromium.org    PrintF(" for concurrent recompilation.\n");
91186e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
91196e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  set_code_no_write_barrier(
91204954674151afa960af66efb4831df06bde727333yangguo@chromium.org      GetIsolate()->builtins()->builtin(Builtins::kCompileOptimizedConcurrent));
91216e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // No write barrier required, since the builtin is part of the root set.
91226e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org}
91236e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
91246e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
91254954674151afa960af66efb4831df06bde727333yangguo@chromium.orgvoid JSFunction::MarkInOptimizationQueue() {
91269259716434187c932704601f700375e53d865de8rossberg@chromium.org  // We can only arrive here via the concurrent-recompilation builtin.  If
9127c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  // break points were set, the code would point to the lazy-compile builtin.
9128e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!GetIsolate()->DebuggerHasBreakPoints());
9129e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsMarkedForConcurrentOptimization() && !IsOptimized());
9130e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(shared()->allows_lazy_compilation() || code()->optimizable());
9131e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(GetIsolate()->concurrent_recompilation_enabled());
91329259716434187c932704601f700375e53d865de8rossberg@chromium.org  if (FLAG_trace_concurrent_recompilation) {
91336e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    PrintF("  ** Queueing ");
9134b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org    ShortPrint();
91359259716434187c932704601f700375e53d865de8rossberg@chromium.org    PrintF(" for concurrent recompilation.\n");
91366e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
91376e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  set_code_no_write_barrier(
91384954674151afa960af66efb4831df06bde727333yangguo@chromium.org      GetIsolate()->builtins()->builtin(Builtins::kInOptimizationQueue));
91396e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // No write barrier required, since the builtin is part of the root set.
9140304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org}
9141a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
91426e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
9143a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgHandle<JSFunction> JSFunction::CloneClosure(Handle<JSFunction> function) {
9144a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  Isolate* isolate = function->GetIsolate();
9145a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  Handle<Map> map(function->map());
9146a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  Handle<SharedFunctionInfo> shared(function->shared());
9147a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  Handle<Context> context(function->context());
9148a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  Handle<JSFunction> clone =
9149a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context);
9150a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
9151a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  if (shared->bound()) {
9152a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    clone->set_function_bindings(function->function_bindings());
9153a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  }
9154a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
9155a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // In typical case, __proto__ of ``function`` is the default Function
9156a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // prototype, which means that SetPrototype below is a no-op.
9157a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // In rare cases when that is not true, we mutate the clone's __proto__.
9158a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  Handle<Object> original_prototype(map->prototype(), isolate);
9159a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  if (*original_prototype != clone->map()->prototype()) {
9160a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    JSObject::SetPrototype(clone, original_prototype, false).Assert();
9161a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  }
9162a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
9163a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  return clone;
9164a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org}
9165a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
9166a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
91675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgvoid SharedFunctionInfo::AddToOptimizedCodeMap(
91685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    Handle<SharedFunctionInfo> shared,
916946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    Handle<Context> native_context,
91705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    Handle<Code> code,
91714954674151afa960af66efb4831df06bde727333yangguo@chromium.org    Handle<FixedArray> literals,
91724954674151afa960af66efb4831df06bde727333yangguo@chromium.org    BailoutId osr_ast_id) {
9173c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  Isolate* isolate = shared->GetIsolate();
9174e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
9175e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(native_context->IsNativeContext());
91764954674151afa960af66efb4831df06bde727333yangguo@chromium.org  STATIC_ASSERT(kEntryLength == 4);
9177c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  Handle<FixedArray> new_code_map;
9178c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  Handle<Object> value(shared->optimized_code_map(), isolate);
9179c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  int old_length;
91805a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (value->IsSmi()) {
91815a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    // No optimized code map.
9182e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK_EQ(0, Smi::cast(*value)->value());
9183e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    // Create 3 entries per context {context, code, literals}.
9184c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    new_code_map = isolate->factory()->NewFixedArray(kInitialLength);
9185c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    old_length = kEntriesStart;
91865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  } else {
91875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    // Copy old map and append one new entry.
9188c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    Handle<FixedArray> old_code_map = Handle<FixedArray>::cast(value);
9189e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK_EQ(-1, shared->SearchOptimizedCodeMap(*native_context, osr_ast_id));
9190c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    old_length = old_code_map->length();
91913484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    new_code_map = FixedArray::CopySize(
9192c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        old_code_map, old_length + kEntryLength);
91934e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    // Zap the old map for the sake of the heap verifier.
9194a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (Heap::ShouldZapGarbage()) {
9195a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      Object** data = old_code_map->data_start();
9196c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      MemsetPointer(data, isolate->heap()->the_hole_value(), old_length);
9197a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    }
91985a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
9199c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  new_code_map->set(old_length + kContextOffset, *native_context);
9200c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  new_code_map->set(old_length + kCachedCodeOffset, *code);
9201c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  new_code_map->set(old_length + kLiteralsOffset, *literals);
9202c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  new_code_map->set(old_length + kOsrAstIdOffset,
9203c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                    Smi::FromInt(osr_ast_id.ToInt()));
9204c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
92055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org#ifdef DEBUG
92064e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
9207e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(new_code_map->get(i + kContextOffset)->IsNativeContext());
9208e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(new_code_map->get(i + kCachedCodeOffset)->IsCode());
9209e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(Code::cast(new_code_map->get(i + kCachedCodeOffset))->kind() ==
92105a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org           Code::OPTIMIZED_FUNCTION);
9211e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(new_code_map->get(i + kLiteralsOffset)->IsFixedArray());
9212e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi());
92135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
92145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org#endif
9215c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  shared->set_optimized_code_map(*new_code_map);
92165a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org}
92175a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
92185a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
92194954674151afa960af66efb4831df06bde727333yangguo@chromium.orgFixedArray* SharedFunctionInfo::GetLiteralsFromOptimizedCodeMap(int index) {
9220e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index > kEntriesStart);
9221d9e468a431d0d87cf3e9898459410eedb1ea9e9aulan@chromium.org  FixedArray* code_map = FixedArray::cast(optimized_code_map());
9222d9e468a431d0d87cf3e9898459410eedb1ea9e9aulan@chromium.org  if (!bound()) {
9223d9e468a431d0d87cf3e9898459410eedb1ea9e9aulan@chromium.org    FixedArray* cached_literals = FixedArray::cast(code_map->get(index + 1));
9224e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK_NE(NULL, cached_literals);
92254954674151afa960af66efb4831df06bde727333yangguo@chromium.org    return cached_literals;
9226d9e468a431d0d87cf3e9898459410eedb1ea9e9aulan@chromium.org  }
92274954674151afa960af66efb4831df06bde727333yangguo@chromium.org  return NULL;
92284954674151afa960af66efb4831df06bde727333yangguo@chromium.org}
92294954674151afa960af66efb4831df06bde727333yangguo@chromium.org
92304954674151afa960af66efb4831df06bde727333yangguo@chromium.org
92314954674151afa960af66efb4831df06bde727333yangguo@chromium.orgCode* SharedFunctionInfo::GetCodeFromOptimizedCodeMap(int index) {
9232e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index > kEntriesStart);
92334954674151afa960af66efb4831df06bde727333yangguo@chromium.org  FixedArray* code_map = FixedArray::cast(optimized_code_map());
9234d9e468a431d0d87cf3e9898459410eedb1ea9e9aulan@chromium.org  Code* code = Code::cast(code_map->get(index));
9235e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_NE(NULL, code);
92364954674151afa960af66efb4831df06bde727333yangguo@chromium.org  return code;
9237d9e468a431d0d87cf3e9898459410eedb1ea9e9aulan@chromium.org}
9238d9e468a431d0d87cf3e9898459410eedb1ea9e9aulan@chromium.org
9239d9e468a431d0d87cf3e9898459410eedb1ea9e9aulan@chromium.org
92404e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgvoid SharedFunctionInfo::ClearOptimizedCodeMap() {
92414e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  FixedArray* code_map = FixedArray::cast(optimized_code_map());
92424e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
92434e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // If the next map link slot is already used then the function was
92444e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // enqueued with code flushing and we remove it now.
92454e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (!code_map->get(kNextMapIndex)->IsUndefined()) {
92464e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher();
92474e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    flusher->EvictOptimizedCodeMap(this);
9248906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  }
92494e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
9250e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(code_map->get(kNextMapIndex)->IsUndefined());
92514e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  set_optimized_code_map(Smi::FromInt(0));
9252906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org}
9253906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
9254906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
9255906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.orgvoid SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code,
9256906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org                                                   const char* reason) {
9257c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  DisallowHeapAllocation no_gc;
9258906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  if (optimized_code_map()->IsSmi()) return;
9259906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
9260906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  FixedArray* code_map = FixedArray::cast(optimized_code_map());
9261f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int dst = kEntriesStart;
9262f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int length = code_map->length();
9263f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  for (int src = kEntriesStart; src < length; src += kEntryLength) {
9264e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(code_map->get(src)->IsNativeContext());
9265f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (Code::cast(code_map->get(src + kCachedCodeOffset)) == optimized_code) {
9266f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      // Evict the src entry by not copying it to the dst entry.
9267906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      if (FLAG_trace_opt) {
92684e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org        PrintF("[evicting entry from optimizing code map (%s) for ", reason);
9269906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org        ShortPrint();
9270f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value());
9271f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        if (osr.IsNone()) {
9272f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          PrintF("]\n");
9273f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        } else {
9274f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          PrintF(" (osr ast id %d)]\n", osr.ToInt());
9275f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        }
9276906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      }
9277f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    } else {
9278f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      // Keep the src entry by copying it to the dst entry.
9279f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      if (dst != src) {
9280f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        code_map->set(dst + kContextOffset,
9281f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                      code_map->get(src + kContextOffset));
9282f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        code_map->set(dst + kCachedCodeOffset,
9283f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                      code_map->get(src + kCachedCodeOffset));
9284f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        code_map->set(dst + kLiteralsOffset,
9285f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                      code_map->get(src + kLiteralsOffset));
9286f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        code_map->set(dst + kOsrAstIdOffset,
9287f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                      code_map->get(src + kOsrAstIdOffset));
9288f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      }
9289f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      dst += kEntryLength;
9290906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    }
9291906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  }
9292f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (dst != length) {
92934e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    // Always trim even when array is cleared because of heap verifier.
92943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GetHeap()->RightTrimFixedArray<Heap::FROM_MUTATOR>(code_map, length - dst);
9295f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (code_map->length() == kEntriesStart) ClearOptimizedCodeMap();
9296906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  }
9297906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org}
9298906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
9299906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
93004e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgvoid SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) {
93014e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  FixedArray* code_map = FixedArray::cast(optimized_code_map());
9302e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(shrink_by % kEntryLength == 0);
9303e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(shrink_by <= code_map->length() - kEntriesStart);
93044e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // Always trim even when array is cleared because of heap verifier.
93053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  GetHeap()->RightTrimFixedArray<Heap::FROM_GC>(code_map, shrink_by);
93064e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (code_map->length() == kEntriesStart) {
93074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    ClearOptimizedCodeMap();
93084e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
93094e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org}
93104e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
93114e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
931231c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.orgvoid JSObject::OptimizeAsPrototype(Handle<JSObject> object,
931331c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org                                   PrototypeOptimizationMode mode) {
9314c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  if (object->IsGlobalObject()) return;
931531c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  if (object->IsJSGlobalProxy()) return;
931631c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  if (mode == FAST_PROTOTYPE && !object->map()->is_prototype_map()) {
931731c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    // First normalize to ensure all JSFunctions are CONSTANT.
931831c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0);
931931c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  }
9320c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  if (!object->HasFastProperties()) {
932131c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    JSObject::MigrateSlowToFast(object, 0);
932231c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  }
932331c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  if (mode == FAST_PROTOTYPE && object->HasFastProperties() &&
932431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      !object->map()->is_prototype_map()) {
932531c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    Handle<Map> new_map = Map::Copy(handle(object->map()));
932631c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    JSObject::MigrateToMap(object, new_map);
932731c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    object->map()->set_is_prototype_map(true);
93287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
93297028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org}
93307028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
93317028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
9332e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) {
9333e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  if (!object->map()->is_prototype_map()) return;
933431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  OptimizeAsPrototype(object, FAST_PROTOTYPE);
9335e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
9336e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
9337e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
93385b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgHandle<Object> CacheInitialJSArrayMaps(
93395b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    Handle<Context> native_context, Handle<Map> initial_map) {
9340e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Replace all of the cached initial array maps in the native context with
9341e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // the appropriate transitioned elements kind maps.
93425b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Factory* factory = native_context->GetIsolate()->factory();
93435b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<FixedArray> maps = factory->NewFixedArrayWithHoles(
93445b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      kElementsKindCount, TENURED);
9345e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
93465b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Map> current_map = initial_map;
9347e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  ElementsKind kind = current_map->elements_kind();
9348e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kind == GetInitialFastElementsKind());
93495b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  maps->set(kind, *current_map);
9350e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
9351e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org       i < kFastElementsKindCount; ++i) {
93525b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    Handle<Map> new_map;
9353e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
9354f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    if (current_map->HasElementsTransition()) {
93555b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      new_map = handle(current_map->elements_transition_map());
9356e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(new_map->elements_kind() == next_kind);
9357f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    } else {
93585b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      new_map = Map::CopyAsElementsKind(
93595b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org          current_map, next_kind, INSERT_TRANSITION);
9360f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    }
93615b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    maps->set(next_kind, *new_map);
9362e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    current_map = new_map;
9363e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
93645b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  native_context->set_js_array_maps(*maps);
9365e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return initial_map;
9366e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
9367e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
9368e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
9369ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid JSFunction::SetInstancePrototype(Handle<JSFunction> function,
9370ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                      Handle<Object> value) {
9371011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  Isolate* isolate = function->GetIsolate();
9372011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org
9373e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(value->IsJSReceiver());
93747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
93757028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // Now some logic for the maps of the objects that are created by using this
93767028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // function as a constructor.
9377ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (function->has_initial_map()) {
9378e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // If the function has allocated the initial map replace it with a
9379e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // copy containing the new prototype.  Also complete any in-object
9380e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // slack tracking that is in progress at this point because it is
9381e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    // still tracking the old copy.
9382011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    if (function->IsInobjectSlackTrackingInProgress()) {
9383011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org      function->CompleteInobjectSlackTracking();
9384e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
938531c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org
9386011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    Handle<Map> initial_map(function->initial_map(), isolate);
9387e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
938831c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    if (!initial_map->GetIsolate()->bootstrapper()->IsActive() &&
938931c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org        initial_map->instance_type() == JS_OBJECT_TYPE) {
939031c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      // Put the value in the initial map field until an initial map is needed.
939131c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      // At that point, a new initial map is created and the prototype is put
939231c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      // into the initial map where it belongs.
939331c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      function->set_prototype_or_initial_map(*value);
939431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    } else {
939531c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      Handle<Map> new_map = Map::Copy(initial_map);
939631c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      JSFunction::SetInitialMap(function, new_map, value);
939731c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org
939831c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      // If the function is used as the global Array function, cache the
939931c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      // initial map (and transitioned versions) in the native context.
940031c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      Context* native_context = function->context()->native_context();
940131c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      Object* array_function =
940231c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org          native_context->get(Context::ARRAY_FUNCTION_INDEX);
940331c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      if (array_function->IsJSFunction() &&
940431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org          *function == JSFunction::cast(array_function)) {
940531c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org        CacheInitialJSArrayMaps(handle(native_context, isolate), new_map);
940631c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      }
9407e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
9408e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
9409011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    // Deoptimize all code that embeds the previous initial map.
9410011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    initial_map->dependent_code()->DeoptimizeDependentCodeGroup(
9411011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org        isolate, DependentCode::kInitialMapChangedGroup);
941243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
941343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Put the value in the initial map field until an initial map is
941443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // needed.  At that point, a new initial map is created and the
941543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // prototype is put into the initial map where it belongs.
9416ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    function->set_prototype_or_initial_map(*value);
941743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
9418011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  isolate->heap()->ClearInstanceofCache();
941943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
942043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
942143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9422ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid JSFunction::SetPrototype(Handle<JSFunction> function,
9423ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                              Handle<Object> value) {
9424e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(function->should_have_prototype());
9425ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Handle<Object> construct_prototype = value;
942643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
942788aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  // If the value is not a JSReceiver, store the value in the map's
942843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // constructor field so it can be accessed.  Also, set the prototype
942943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // used for constructing objects to the original object prototype.
943043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // See ECMA-262 13.2.2.
943188aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  if (!value->IsJSReceiver()) {
943243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Copy the map so this does not affect unrelated functions.
94339a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    // Remove map transitions because they point to maps with a
94349a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    // different prototype.
9435ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<Map> new_map = Map::Copy(handle(function->map()));
9436753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
943797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    JSObject::MigrateToMap(function, new_map);
9438ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    new_map->set_constructor(*value);
9439c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    new_map->set_non_instance_prototype(true);
9440ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Isolate* isolate = new_map->GetIsolate();
9441ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    construct_prototype = handle(
9442ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        isolate->context()->native_context()->initial_object_prototype(),
9443ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        isolate);
944443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
9445ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    function->map()->set_non_instance_prototype(false);
944643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
944743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9448ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return SetInstancePrototype(function, construct_prototype);
944943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
945043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
945143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9452a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgbool JSFunction::RemovePrototype() {
945346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Context* native_context = context()->native_context();
9454486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  Map* no_prototype_map = shared()->strict_mode() == SLOPPY
9455486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      ? native_context->sloppy_function_without_prototype_map()
9456486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      : native_context->strict_function_without_prototype_map();
9457ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
9458a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (map() == no_prototype_map) return true;
9459ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
9460a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org#ifdef DEBUG
9461a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (map() != (shared()->strict_mode() == SLOPPY
9462486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                   ? native_context->sloppy_function_map()
9463a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                   : native_context->strict_function_map())) {
9464a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    return false;
9465a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  }
9466a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org#endif
9467ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
9468ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  set_map(no_prototype_map);
9469c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value());
9470a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  return true;
94714111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org}
94724111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
94734111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
947431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.orgvoid JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
947531c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org                               Handle<Object> prototype) {
947631c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  if (prototype->IsJSObject()) {
947731c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    Handle<JSObject> js_proto = Handle<JSObject>::cast(prototype);
947831c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    JSObject::OptimizeAsPrototype(js_proto, FAST_PROTOTYPE);
94798640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  }
948031c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  map->set_prototype(*prototype);
94818640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  function->set_prototype_or_initial_map(*map);
94828640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  map->set_constructor(*function);
94838640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
94848640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
94858640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
9486057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgvoid JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
9487057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  if (function->has_initial_map()) return;
9488057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Isolate* isolate = function->GetIsolate();
9489057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
9490057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  // First create a new map with the size and number of in-object properties
9491057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  // suggested by the function.
9492057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  InstanceType instance_type;
9493057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  int instance_size;
9494057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  int in_object_properties;
9495057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  if (function->shared()->is_generator()) {
9496057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    instance_type = JS_GENERATOR_OBJECT_TYPE;
9497057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    instance_size = JSGeneratorObject::kSize;
9498057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    in_object_properties = 0;
9499057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  } else {
9500057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    instance_type = JS_OBJECT_TYPE;
9501057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    instance_size = function->shared()->CalculateInstanceSize();
9502057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    in_object_properties = function->shared()->CalculateInObjectProperties();
9503057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  }
9504057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size);
9505057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
9506057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  // Fetch or allocate prototype.
9507057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Handle<Object> prototype;
9508057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  if (function->has_instance_prototype()) {
9509057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    prototype = handle(function->instance_prototype(), isolate);
9510057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  } else {
9511057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    prototype = isolate->factory()->NewFunctionPrototype(function);
9512057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  }
9513057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  map->set_inobject_properties(in_object_properties);
9514057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  map->set_unused_property_fields(in_object_properties);
9515e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(map->has_fast_object_elements());
9516057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
9517057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  // Finally link initial map and constructor function.
951831c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  JSFunction::SetInitialMap(function, map, Handle<JSReceiver>::cast(prototype));
9519011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org
9520011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  if (!function->shared()->is_generator()) {
9521011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    function->StartInobjectSlackTracking();
9522011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  }
9523057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org}
9524057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
9525057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
9526de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.orgvoid JSFunction::SetInstanceClassName(String* name) {
952743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  shared()->set_instance_class_name(name);
952843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
952943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
953043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9531023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.orgvoid JSFunction::PrintName(FILE* out) {
953283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  SmartArrayPointer<char> name = shared()->DebugName()->ToCString();
9533afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  PrintF(out, "%s", name.get());
9534a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
9535a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
953746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgContext* JSFunction::NativeContextFromLiterals(FixedArray* literals) {
953846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return Context::cast(literals->get(JSFunction::kLiteralNativeContextIndex));
9539236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org}
9540236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
9541236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
95421e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// The filter is a pattern that matches function names in this way:
95431e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org//   "*"      all; the default
95441e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org//   "-"      all but the top-level function
95451e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org//   "-name"  all but the function "name"
95461e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org//   ""       only the top-level function
95471e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org//   "name"   only the function "name"
95481e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org//   "name*"  only functions starting with "name"
95497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org//   "~"      none; the tilde is not an identifier
95501e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.orgbool JSFunction::PassesFilter(const char* raw_filter) {
95511e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  if (*raw_filter == '*') return true;
9552906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  String* name = shared()->DebugName();
95531e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  Vector<const char> filter = CStrVector(raw_filter);
95541e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  if (filter.length() == 0) return name->length() == 0;
9555ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  if (filter[0] == '-') {
9556e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org    // Negative filter.
9557ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    if (filter.length() == 1) {
9558ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org      return (name->length() != 0);
9559e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org    } else if (name->IsUtf8EqualTo(filter.SubVector(1, filter.length()))) {
9560e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org      return false;
9561e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org    }
9562e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org    if (filter[filter.length() - 1] == '*' &&
9563e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org        name->IsUtf8EqualTo(filter.SubVector(1, filter.length() - 1), true)) {
9564e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org      return false;
9565ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    }
9566e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org    return true;
9567e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org
9568ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  } else if (name->IsUtf8EqualTo(filter)) {
95691e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    return true;
9570906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  }
95711e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  if (filter[filter.length() - 1] == '*' &&
95721e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      name->IsUtf8EqualTo(filter.SubVector(0, filter.length() - 1), true)) {
95731e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    return true;
95741e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  }
95751e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  return false;
9576906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org}
9577906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
9578906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
95799fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgvoid Oddball::Initialize(Isolate* isolate,
95809fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                         Handle<Oddball> oddball,
95819fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                         const char* to_string,
95829fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                         Handle<Object> to_number,
95839fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                         byte kind) {
95849fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<String> internalized_to_string =
9585f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      isolate->factory()->InternalizeUtf8String(to_string);
95869fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  oddball->set_to_string(*internalized_to_string);
95879fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  oddball->set_to_number(*to_number);
95889fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  oddball->set_kind(kind);
95899fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
95909fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
95919fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
95929fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgvoid Script::InitLineEnds(Handle<Script> script) {
95939fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (!script->line_ends()->IsUndefined()) return;
95949fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
95959fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Isolate* isolate = script->GetIsolate();
95969fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
95979fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (!script->source()->IsString()) {
9598e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(script->source()->IsUndefined());
95999fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<FixedArray> empty = isolate->factory()->NewFixedArray(0);
96009fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    script->set_line_ends(*empty);
9601e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(script->line_ends()->IsFixedArray());
96029fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    return;
9603303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
96049fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96059fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<String> src(String::cast(script->source()), isolate);
96069fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96079fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<FixedArray> array = String::CalculateLineEnds(src, true);
96089fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96099fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (*array != isolate->heap()->empty_fixed_array()) {
96109fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    array->set_map(isolate->heap()->fixed_cow_array_map());
96119fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
96129fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96139fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  script->set_line_ends(*array);
9614e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(script->line_ends()->IsFixedArray());
96159fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
96169fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96179fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96189fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgint Script::GetColumnNumber(Handle<Script> script, int code_pos) {
96199fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int line_number = GetLineNumber(script, code_pos);
96209fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (line_number == -1) return -1;
96219fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96229fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  DisallowHeapAllocation no_allocation;
96239fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
96249fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  line_number = line_number - script->line_offset()->value();
96259fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (line_number == 0) return code_pos + script->column_offset()->value();
96269fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int prev_line_end_pos =
96279fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      Smi::cast(line_ends_array->get(line_number - 1))->value();
96289fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return code_pos - (prev_line_end_pos + 1);
96299fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
96309fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96319fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96329fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgint Script::GetLineNumberWithArray(int code_pos) {
96339fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  DisallowHeapAllocation no_allocation;
9634e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(line_ends()->IsFixedArray());
96359fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  FixedArray* line_ends_array = FixedArray::cast(line_ends());
96369fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int line_ends_len = line_ends_array->length();
96379fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (line_ends_len == 0) return -1;
96389fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96399fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) {
96409fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    return line_offset()->value();
96419fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
96429fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96439fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int left = 0;
96449fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int right = line_ends_len;
96459fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  while (int half = (right - left) / 2) {
96469fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if ((Smi::cast(line_ends_array->get(left + half)))->value() > code_pos) {
96479fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      right -= half;
96489fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    } else {
96499fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      left += half;
96509fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
96519fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
96529fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return right + line_offset()->value();
96539fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
96549fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96559fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96569fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgint Script::GetLineNumber(Handle<Script> script, int code_pos) {
96579fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  InitLineEnds(script);
96589fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return script->GetLineNumberWithArray(code_pos);
96599fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
96609fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96619fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96629fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgint Script::GetLineNumber(int code_pos) {
96639fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  DisallowHeapAllocation no_allocation;
96649fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (!line_ends()->IsUndefined()) return GetLineNumberWithArray(code_pos);
96659fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Slow mode: we do not have line_ends. We have to iterate through source.
96679fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (!source()->IsString()) return -1;
96689fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96699fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  String* source_string = String::cast(source());
96709fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int line = 0;
96719fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int len = source_string->length();
96729fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  for (int pos = 0; pos < len; pos++) {
96739fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (pos == code_pos) break;
96749fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (source_string->Get(pos) == '\n') line++;
96759fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
96769fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return line;
96779fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
96789fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96799fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96809fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgHandle<Object> Script::GetNameOrSourceURL(Handle<Script> script) {
96819fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Isolate* isolate = script->GetIsolate();
96829fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<String> name_or_source_url_key =
96839fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      isolate->factory()->InternalizeOneByteString(
96842c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org          STATIC_CHAR_VECTOR("nameOrSourceURL"));
96859fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<JSObject> script_wrapper = Script::GetWrapper(script);
96869fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<Object> property = Object::GetProperty(
96879fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      script_wrapper, name_or_source_url_key).ToHandleChecked();
9688e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(property->IsJSFunction());
96899fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<JSFunction> method = Handle<JSFunction>::cast(property);
96909fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<Object> result;
96919fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Do not check against pending exception, since this function may be called
96929fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // when an exception has already been pending.
96939fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (!Execution::TryCall(method, script_wrapper, 0, NULL).ToHandle(&result)) {
96949fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    return isolate->factory()->undefined_value();
96959fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
96969fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return result;
96979fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
96989fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
96999fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
97009fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org// Wrappers for scripts are kept alive and cached in weak global
97019fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org// handles referred from foreign objects held by the scripts as long as
97029fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org// they are used. When they are not used anymore, the garbage
97039fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org// collector will call the weak callback on the global handle
97049fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org// associated with the wrapper and get rid of both the wrapper and the
97059fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org// handle.
97067c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.orgstatic void ClearWrapperCacheWeakCallback(
97079fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    const v8::WeakCallbackData<v8::Value, void>& data) {
97089fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Object** location = reinterpret_cast<Object**>(data.GetParameter());
97099fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  JSValue* wrapper = JSValue::cast(*location);
97107c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org  Script::cast(wrapper->value())->ClearWrapperCache();
97117c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org}
97127c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org
97137c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org
97147c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.orgvoid Script::ClearWrapperCache() {
97157c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org  Foreign* foreign = wrapper();
97167c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org  Object** location = reinterpret_cast<Object**>(foreign->foreign_address());
9717e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(foreign->foreign_address(), reinterpret_cast<Address>(location));
97189fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  foreign->set_foreign_address(0);
97199fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  GlobalHandles::Destroy(location);
97207c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org  GetIsolate()->counters()->script_wrappers()->Decrement();
97219fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
97229fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
97239fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
97249fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgHandle<JSObject> Script::GetWrapper(Handle<Script> script) {
97259fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (script->wrapper()->foreign_address() != NULL) {
97269fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // Return a handle for the existing script wrapper from the cache.
97279fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    return Handle<JSValue>(
97289fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        *reinterpret_cast<JSValue**>(script->wrapper()->foreign_address()));
97299fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
97309fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Isolate* isolate = script->GetIsolate();
97319fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Construct a new script wrapper.
97329fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  isolate->counters()->script_wrappers()->Increment();
97339fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<JSFunction> constructor = isolate->script_function();
97349fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<JSValue> result =
97359fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
97369fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
97379fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  result->set_value(*script);
97389fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
97399fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Create a new weak global handle and use it to cache the wrapper
97409fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // for future use. The cache will automatically be cleared by the
97419fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // garbage collector when it is not used anymore.
97429fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<Object> handle = isolate->global_handles()->Create(*result);
97439fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  GlobalHandles::MakeWeak(handle.location(),
97449fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                          reinterpret_cast<void*>(handle.location()),
97457c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org                          &ClearWrapperCacheWeakCallback);
97469fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  script->wrapper()->set_foreign_address(
97479fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      reinterpret_cast<Address>(handle.location()));
97489fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return result;
974943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
975043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
975143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9752b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.orgString* SharedFunctionInfo::DebugName() {
9753b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org  Object* n = name();
9754b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org  if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name();
9755b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org  return String::cast(n);
9756b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org}
9757b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org
9758b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org
9759f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgbool SharedFunctionInfo::HasSourceCode() const {
976043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return !script()->IsUndefined() &&
97610b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org         !reinterpret_cast<Script*>(script())->source()->IsUndefined();
976243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
976343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
976443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
976578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgHandle<Object> SharedFunctionInfo::GetSourceCode() {
976678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  if (!HasSourceCode()) return GetIsolate()->factory()->undefined_value();
976778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  Handle<String> source(String::cast(Script::cast(script())->source()));
97688e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  return GetIsolate()->factory()->NewSubString(
97698e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org      source, start_position(), end_position());
977043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
977143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
977243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
97730cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.orgbool SharedFunctionInfo::IsInlineable() {
97740cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // Check that the function has a script associated with it.
97750cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  if (!script()->IsScript()) return false;
97760cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  if (optimization_disabled()) return false;
97770cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // If we never ran this (unlikely) then lets try to optimize it.
97780cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  if (code()->kind() != Code::FUNCTION) return true;
97790cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  return code()->optimizable();
97800cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org}
97810cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
97820cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
9783a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgint SharedFunctionInfo::SourceSize() {
9784a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return end_position() - start_position();
9785a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
9786a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9787a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9788911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgint SharedFunctionInfo::CalculateInstanceSize() {
9789911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  int instance_size =
9790911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org      JSObject::kHeaderSize +
9791911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org      expected_nof_properties() * kPointerSize;
9792911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  if (instance_size > JSObject::kMaxInstanceSize) {
9793911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org    instance_size = JSObject::kMaxInstanceSize;
9794911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  }
9795911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  return instance_size;
9796911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org}
9797911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org
9798911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org
9799911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgint SharedFunctionInfo::CalculateInObjectProperties() {
9800911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize;
9801911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org}
9802911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org
9803911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org
9804f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org// Output the source code without any allocation in the heap.
9805f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgOStream& operator<<(OStream& os, const SourceCodeOf& v) {
9806f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  const SharedFunctionInfo* s = v.value;
980743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // For some native functions there is no source.
9808f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  if (!s->HasSourceCode()) return os << "<No Source>";
980943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9810c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Get the source for the script which this function came from.
981143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Don't use String::cast because we don't want more assertion errors while
981243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // we are already creating a stack dump.
981343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  String* script_source =
9814f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      reinterpret_cast<String*>(Script::cast(s->script())->source());
981543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9816f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  if (!script_source->LooksValid()) return os << "<Invalid Source>";
981743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9818f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  if (!s->is_toplevel()) {
9819f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "function ";
9820f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    Object* name = s->name();
982143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (name->IsString() && String::cast(name)->length() > 0) {
9822f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      String::cast(name)->PrintUC16(os);
982343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
982443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
982543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9826f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  int len = s->end_position() - s->start_position();
9827f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  if (len <= v.max_length || v.max_length < 0) {
9828f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    script_source->PrintUC16(os, s->start_position(), s->end_position());
9829f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    return os;
9830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
9831f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    script_source->PrintUC16(os, s->start_position(),
9832f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org                             s->start_position() + v.max_length);
9833f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    return os << "...\n";
9834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
9835a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
9836a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9837a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9838a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstatic bool IsCodeEquivalent(Code* code, Code* recompiled) {
9839a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (code->instruction_size() != recompiled->instruction_size()) return false;
9840a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ByteArray* code_relocation = code->relocation_info();
9841a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ByteArray* recompiled_relocation = recompiled->relocation_info();
9842a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int length = code_relocation->length();
9843a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (length != recompiled_relocation->length()) return false;
9844a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int compare = memcmp(code_relocation->GetDataStartAddress(),
9845a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                       recompiled_relocation->GetDataStartAddress(),
9846a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                       length);
9847a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return compare == 0;
9848a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
9849a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9850a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9851a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid SharedFunctionInfo::EnableDeoptimizationSupport(Code* recompiled) {
9852e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!has_deoptimization_support());
985379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
9854a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Code* code = this->code();
9855a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (IsCodeEquivalent(code, recompiled)) {
9856a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Copy the deoptimization data from the recompiled code.
9857a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    code->set_deoptimization_data(recompiled->deoptimization_data());
9858a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    code->set_has_deoptimization_support(true);
985943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
9860a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // TODO(3025757): In case the recompiled isn't equivalent to the
9861a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // old code, we have to replace it. We should try to avoid this
9862a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // altogether because it flushes valuable type feedback by
9863a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // effectively resetting all IC state.
98649768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org    ReplaceCode(recompiled);
986543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
9866e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(has_deoptimization_support());
9867a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
9868a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9869a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9870594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid SharedFunctionInfo::DisableOptimization(BailoutReason reason) {
9871ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // Disable optimization for the shared function info and mark the
9872ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // code as non-optimizable. The marker on the shared function info
9873ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // is there because we flush non-optimized code thereby loosing the
9874ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // non-optimizable information for the code. When the code is
9875ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // regenerated and set on the shared function info it is marked as
9876ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // non-optimizable if optimization is disabled for the shared
9877ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // function info.
9878ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  set_optimization_disabled(true);
98792c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  set_bailout_reason(reason);
9880ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // Code should be the lazy compilation stub or else unoptimized.  If the
9881ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // latter, disable optimization for the code too.
9882e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(code()->kind() == Code::FUNCTION || code()->kind() == Code::BUILTIN);
9883ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  if (code()->kind() == Code::FUNCTION) {
9884ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    code()->set_optimizable(false);
9885ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  }
9886fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  PROFILE(GetIsolate(), CodeDisableOptEvent(code(), this));
9887ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  if (FLAG_trace_opt) {
9888906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    PrintF("[disabled optimization for ");
9889906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    ShortPrint();
9890594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    PrintF(", reason: %s]\n", GetBailoutReason(reason));
9891ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  }
9892ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org}
9893ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
9894ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
9895471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgbool SharedFunctionInfo::VerifyBailoutId(BailoutId id) {
9896e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!id.IsNone());
9897a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Code* unoptimized = code();
9898a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DeoptimizationOutputData* data =
9899a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      DeoptimizationOutputData::cast(unoptimized->deoptimization_data());
9900a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this);
9901a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  USE(ignore);
9902e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  return true;  // Return true if there was no DCHECK.
990343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
990443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
990543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9906011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.orgvoid JSFunction::StartInobjectSlackTracking() {
9907e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(has_initial_map() && !IsInobjectSlackTrackingInProgress());
99084a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
9909b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  if (!FLAG_clever_optimizations) return;
9910011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  Map* map = initial_map();
9911b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
99124a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  // Only initiate the tracking the first time.
9913011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  if (map->done_inobject_slack_tracking()) return;
9914011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  map->set_done_inobject_slack_tracking(true);
99154a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
99164a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  // No tracking during the snapshot construction phase.
9917a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  Isolate* isolate = GetIsolate();
9918fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  if (isolate->serializer_enabled()) return;
99194a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
99204a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  if (map->unused_property_fields() == 0) return;
99214a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
9922011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  map->set_construction_count(kGenerousAllocationCount);
99234a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org}
99244a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
99254a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
99261456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid SharedFunctionInfo::ResetForNewContext(int new_ic_age) {
99271456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  code()->ClearInlineCaches();
9928a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  // If we clear ICs, we need to clear the type feedback vector too, since
9929a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  // CallICs are synced with a feedback vector slot.
9930a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  ClearTypeFeedbackInfo();
99311456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  set_ic_age(new_ic_age);
99326b9c2a06402995d2a7074d68e4560b3b62d82451ulan@chromium.org  if (code()->kind() == Code::FUNCTION) {
99336b9c2a06402995d2a7074d68e4560b3b62d82451ulan@chromium.org    code()->set_profiler_ticks(0);
99346b9c2a06402995d2a7074d68e4560b3b62d82451ulan@chromium.org    if (optimization_disabled() &&
9935de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org        opt_count() >= FLAG_max_opt_count) {
99366b9c2a06402995d2a7074d68e4560b3b62d82451ulan@chromium.org      // Re-enable optimizations if they were disabled due to opt_count limit.
99376b9c2a06402995d2a7074d68e4560b3b62d82451ulan@chromium.org      set_optimization_disabled(false);
99386b9c2a06402995d2a7074d68e4560b3b62d82451ulan@chromium.org      code()->set_optimizable(true);
99396b9c2a06402995d2a7074d68e4560b3b62d82451ulan@chromium.org    }
99406b9c2a06402995d2a7074d68e4560b3b62d82451ulan@chromium.org    set_opt_count(0);
99417028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    set_deopt_count(0);
99421456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  }
99431456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}
99441456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
99451456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
99464a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgstatic void GetMinInobjectSlack(Map* map, void* data) {
99474a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int slack = map->unused_property_fields();
99484a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  if (*reinterpret_cast<int*>(data) > slack) {
99494a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    *reinterpret_cast<int*>(data) = slack;
99504a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  }
99514a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org}
99524a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
99534a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
99544a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgstatic void ShrinkInstanceSize(Map* map, void* data) {
99554a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int slack = *reinterpret_cast<int*>(data);
99564a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  map->set_inobject_properties(map->inobject_properties() - slack);
99574a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  map->set_unused_property_fields(map->unused_property_fields() - slack);
99584a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  map->set_instance_size(map->instance_size() - slack * kPointerSize);
99594a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
99604a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  // Visitor id might depend on the instance size, recalculate it.
99614a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  map->set_visitor_id(StaticVisitorBase::GetVisitorId(map));
99624a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org}
99634a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
99644a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
9965011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.orgvoid JSFunction::CompleteInobjectSlackTracking() {
9966e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(has_initial_map());
9967011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  Map* map = initial_map();
99684a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
9969e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(map->done_inobject_slack_tracking());
9970011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  map->set_construction_count(kNoSlackTracking);
99714a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
99724a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  int slack = map->unused_property_fields();
99734a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  map->TraverseTransitionTree(&GetMinInobjectSlack, &slack);
99744a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  if (slack != 0) {
99754a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    // Resize the initial map and all maps in its transition tree.
99764a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    map->TraverseTransitionTree(&ShrinkInstanceSize, &slack);
99774a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  }
99784a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org}
99794a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
99804a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
99814954674151afa960af66efb4831df06bde727333yangguo@chromium.orgint SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context,
99824954674151afa960af66efb4831df06bde727333yangguo@chromium.org                                               BailoutId osr_ast_id) {
9983c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  DisallowHeapAllocation no_gc;
9984e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(native_context->IsNativeContext());
9985d9e468a431d0d87cf3e9898459410eedb1ea9e9aulan@chromium.org  if (!FLAG_cache_optimized_code) return -1;
99865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Object* value = optimized_code_map();
99875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (!value->IsSmi()) {
99885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    FixedArray* optimized_code_map = FixedArray::cast(value);
99895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    int length = optimized_code_map->length();
99904954674151afa960af66efb4831df06bde727333yangguo@chromium.org    Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt());
99914e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    for (int i = kEntriesStart; i < length; i += kEntryLength) {
99924954674151afa960af66efb4831df06bde727333yangguo@chromium.org      if (optimized_code_map->get(i + kContextOffset) == native_context &&
99934954674151afa960af66efb4831df06bde727333yangguo@chromium.org          optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) {
99944954674151afa960af66efb4831df06bde727333yangguo@chromium.org        return i + kCachedCodeOffset;
99955a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      }
99965a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    }
9997906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    if (FLAG_trace_opt) {
9998906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      PrintF("[didn't find optimized code in optimized code map for ");
9999906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      ShortPrint();
10000906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      PrintF("]\n");
10001906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    }
100025a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
100035a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return -1;
100045a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org}
100055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
100065a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
1000764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org#define DECLARE_TAG(ignore1, name, ignore2) name,
1000864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgconst char* const VisitorSynchronization::kTags[
1000964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    VisitorSynchronization::kNumberOfSyncTags] = {
1001064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG)
1001164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org};
1001264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org#undef DECLARE_TAG
1001364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
1001464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
1001564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org#define DECLARE_TAG(ignore1, ignore2, name) name,
1001664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgconst char* const VisitorSynchronization::kTagNames[
1001764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    VisitorSynchronization::kNumberOfSyncTags] = {
1001864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG)
1001964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org};
1002064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org#undef DECLARE_TAG
1002164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
1002264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
1002343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid ObjectVisitor::VisitCodeTarget(RelocInfo* rinfo) {
10024e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
100252bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
100262bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  Object* old_target = target;
100272bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  VisitPointer(&target);
100282bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  CHECK_EQ(target, old_target);  // VisitPointer doesn't change Code* *target.
1002943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1003043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1003143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10032e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid ObjectVisitor::VisitCodeAgeSequence(RelocInfo* rinfo) {
10033e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode()));
10034e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Object* stub = rinfo->code_age_stub();
10035e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (stub) {
10036e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    VisitPointer(&stub);
10037e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
10038e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
10039e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
10040e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
10041145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.comvoid ObjectVisitor::VisitCodeEntry(Address entry_address) {
10042145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  Object* code = Code::GetObjectFromEntryAddress(entry_address);
10043145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  Object* old_code = code;
10044145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  VisitPointer(&code);
10045145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  if (code != old_code) {
10046145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com    Memory::Address_at(entry_address) = reinterpret_cast<Code*>(code)->entry();
10047145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  }
10048145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com}
10049145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com
10050145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com
1005141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgvoid ObjectVisitor::VisitCell(RelocInfo* rinfo) {
10052e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rinfo->rmode() == RelocInfo::CELL);
10053a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Object* cell = rinfo->target_cell();
10054a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Object* old_cell = cell;
10055a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  VisitPointer(&cell);
10056a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (cell != old_cell) {
1005741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    rinfo->set_target_cell(reinterpret_cast<Cell*>(cell));
10058a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
10059a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
10060a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10061a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1006243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) {
10063e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((RelocInfo::IsJSReturn(rinfo->rmode()) &&
100642356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org          rinfo->IsPatchedReturnSequence()) ||
100652356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org         (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
100662356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org          rinfo->IsPatchedDebugBreakSlotSequence()));
100672bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
100682bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  Object* old_target = target;
100692bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  VisitPointer(&target);
100702bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  CHECK_EQ(target, old_target);  // VisitPointer doesn't change Code* *target.
1007143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1007243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10073e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
10074b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.orgvoid ObjectVisitor::VisitEmbeddedPointer(RelocInfo* rinfo) {
10075e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
10076057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Object* p = rinfo->target_object();
10077057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  VisitPointer(&p);
10078b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org}
10079b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
10080e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1008104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.orgvoid ObjectVisitor::VisitExternalReference(RelocInfo* rinfo) {
10082057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Address p = rinfo->target_reference();
10083057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  VisitExternalReference(&p);
1008404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org}
10085b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
10086e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
10087a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Code::InvalidateRelocation() {
1008893720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  InvalidateEmbeddedObjects();
10089c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  set_relocation_info(GetHeap()->empty_byte_array());
10090a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
10091a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10092a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10093f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgvoid Code::InvalidateEmbeddedObjects() {
10094f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Object* undefined = GetHeap()->undefined_value();
1009526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  Cell* undefined_cell = GetHeap()->undefined_cell();
1009626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
1009726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org                  RelocInfo::ModeMask(RelocInfo::CELL);
10098f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
10099f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    RelocInfo::Mode mode = it.rinfo()->rmode();
10100f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    if (mode == RelocInfo::EMBEDDED_OBJECT) {
10101f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      it.rinfo()->set_target_object(undefined, SKIP_WRITE_BARRIER);
1010226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org    } else if (mode == RelocInfo::CELL) {
1010326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org      it.rinfo()->set_target_cell(undefined_cell, SKIP_WRITE_BARRIER);
10104f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    }
10105f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  }
10106f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org}
10107f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
10108f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
10109c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgvoid Code::Relocate(intptr_t delta) {
1011043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) {
101116a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    it.rinfo()->apply(delta, SKIP_ICACHE_FLUSH);
1011243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
101135de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  CpuFeatures::FlushICache(instruction_start(), instruction_size());
1011443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1011543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1011643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1011743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Code::CopyFrom(const CodeDesc& desc) {
10118e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(Marking::Color(this) == Marking::WHITE_OBJECT);
10119394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1012043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // copy code
10121f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  CopyBytes(instruction_start(), desc.buffer,
10122f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org            static_cast<size_t>(desc.instr_size));
1012343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1012443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // copy reloc info
10125c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  CopyBytes(relocation_start(),
10126c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org            desc.buffer + desc.buffer_size - desc.reloc_size,
10127f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org            static_cast<size_t>(desc.reloc_size));
1012843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1012943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // unbox handles and relocate
101309d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  intptr_t delta = instruction_start() - desc.buffer;
1013143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int mode_mask = RelocInfo::kCodeTargetMask |
10132236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org                  RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
1013341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                  RelocInfo::ModeMask(RelocInfo::CELL) |
101346e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org                  RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
1013543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                  RelocInfo::kApplyMask;
101366e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // Needed to find target_object and runtime_entry on X64
101376e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  Assembler* origin = desc.origin;
1013879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowDeferredHandleDereference embedding_raw_address;
1013943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
10140236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    RelocInfo::Mode mode = it.rinfo()->rmode();
10141236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    if (mode == RelocInfo::EMBEDDED_OBJECT) {
10142c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org      Handle<Object> p = it.rinfo()->target_object_handle(origin);
101436a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      it.rinfo()->set_target_object(*p, SKIP_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
1014441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    } else if (mode == RelocInfo::CELL) {
1014541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      Handle<Cell> cell  = it.rinfo()->target_cell_handle();
101466a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      it.rinfo()->set_target_cell(*cell, SKIP_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
10147236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    } else if (RelocInfo::IsCodeTarget(mode)) {
1014843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // rewrite code handles in inline cache targets to direct
1014943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // pointers to the first instruction in the code object
10150c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org      Handle<Object> p = it.rinfo()->target_object_handle(origin);
1015143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Code* code = Code::cast(*p);
10152394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      it.rinfo()->set_target_address(code->instruction_start(),
101536a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                     SKIP_WRITE_BARRIER,
101546a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                     SKIP_ICACHE_FLUSH);
101556e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    } else if (RelocInfo::IsRuntimeEntry(mode)) {
101566e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      Address p = it.rinfo()->target_runtime_entry(origin);
101576a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      it.rinfo()->set_target_runtime_entry(p, SKIP_WRITE_BARRIER,
101586a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                                           SKIP_ICACHE_FLUSH);
10159c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    } else if (mode == RelocInfo::CODE_AGE_SEQUENCE) {
10160c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      Handle<Object> p = it.rinfo()->code_age_stub_handle(origin);
10161c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      Code* code = Code::cast(*p);
101626a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      it.rinfo()->set_code_age_stub(code, SKIP_ICACHE_FLUSH);
1016343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
101646a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      it.rinfo()->apply(delta, SKIP_ICACHE_FLUSH);
1016543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1016643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
101675de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  CpuFeatures::FlushICache(instruction_start(), instruction_size());
1016843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1016943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1017043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1017143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Locate the source position which is closest to the address in the code. This
1017243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// is using the source position information embedded in the relocation info.
1017343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The position returned is relative to the beginning of the script where the
1017443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// source for this function is found.
1017543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint Code::SourcePosition(Address pc) {
1017643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int distance = kMaxInt;
10177236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  int position = RelocInfo::kNoPosition;  // Initially no position found.
1017843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Run through all the relocation info to find the best matching source
1017943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // position. All the code needs to be considered as the sequence of the
1018043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // instructions in the code does not necessarily follow the same order as the
1018143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // source.
1018243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RelocIterator it(this, RelocInfo::kPositionMask);
1018343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (!it.done()) {
10184236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    // Only look at positions after the current pc.
10185236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    if (it.rinfo()->pc() < pc) {
10186236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      // Get position and distance.
10187c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
10188c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      int dist = static_cast<int>(pc - it.rinfo()->pc());
10189c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      int pos = static_cast<int>(it.rinfo()->data());
10190236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      // If this position is closer than the current candidate or if it has the
10191236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      // same distance as the current candidate and the position is higher then
10192236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      // this position is the new candidate.
10193236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      if ((dist < distance) ||
10194236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org          (dist == distance && pos > position)) {
10195236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org        position = pos;
10196236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org        distance = dist;
10197236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org      }
1019843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1019943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    it.next();
1020043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1020143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return position;
1020243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1020343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1020443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1020543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Same as Code::SourcePosition above except it only looks for statement
1020643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// positions.
1020743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint Code::SourceStatementPosition(Address pc) {
1020843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // First find the position as close as possible using all position
1020943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // information.
1021043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int position = SourcePosition(pc);
1021143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Now find the closest statement position before the position.
1021243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int statement_position = 0;
1021343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  RelocIterator it(this, RelocInfo::kPositionMask);
1021443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  while (!it.done()) {
10215236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    if (RelocInfo::IsStatementPosition(it.rinfo()->rmode())) {
10216c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org      int p = static_cast<int>(it.rinfo()->data());
1021743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (statement_position < p && p <= position) {
1021843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        statement_position = p;
1021943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1022043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1022143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    it.next();
1022243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1022343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return statement_position;
1022443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1022543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1022643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10227c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgSafepointEntry Code::GetSafepointEntry(Address pc) {
10228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SafepointTable table(this);
102296474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  return table.FindEntry(pc);
10230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
10231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10232a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
102331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgObject* Code::FindNthObject(int n, Map* match_map) {
10234e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_inline_cache_stub());
1023579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
10236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
10237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (RelocIterator it(this, mask); !it.done(); it.next()) {
10238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    RelocInfo* info = it.rinfo();
10239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Object* object = info->target_object();
102401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (object->IsHeapObject()) {
102411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      if (HeapObject::cast(object)->map() == match_map) {
102421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        if (--n == 0) return object;
102431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      }
102441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    }
10245a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
10246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return NULL;
10247a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
10248a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10249a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
102500f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgAllocationSite* Code::FindFirstAllocationSite() {
102510f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  Object* result = FindNthObject(1, GetHeap()->allocation_site_map());
102520f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  return (result != NULL) ? AllocationSite::cast(result) : NULL;
102530f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org}
102540f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
102550f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
102561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgMap* Code::FindFirstMap() {
102571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Object* result = FindNthObject(1, GetHeap()->meta_map());
102581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return (result != NULL) ? Map::cast(result) : NULL;
102591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
102601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
102611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
102629801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.orgvoid Code::FindAndReplace(const FindAndReplacePattern& pattern) {
10263e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_inline_cache_stub() || is_handler());
1026479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
10265ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
102669801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org  STATIC_ASSERT(FindAndReplacePattern::kMaxCount < 32);
102679801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org  int current_pattern = 0;
10268ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  for (RelocIterator it(this, mask); !it.done(); it.next()) {
10269ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    RelocInfo* info = it.rinfo();
10270ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    Object* object = info->target_object();
102711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (object->IsHeapObject()) {
102729801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org      Map* map = HeapObject::cast(object)->map();
102739801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org      if (map == *pattern.find_[current_pattern]) {
102749801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org        info->set_target_object(*pattern.replace_[current_pattern]);
102759801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org        if (++current_pattern == pattern.count_) return;
102761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      }
10277ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    }
10278ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
10279ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  UNREACHABLE();
10280ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
10281ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
10282ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
102834a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgvoid Code::FindAllMaps(MapHandleList* maps) {
10284e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_inline_cache_stub());
1028579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
102864a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
102874a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  for (RelocIterator it(this, mask); !it.done(); it.next()) {
102884a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    RelocInfo* info = it.rinfo();
102894a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Object* object = info->target_object();
10290af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    if (object->IsMap()) maps->Add(handle(Map::cast(object)));
10291af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
10292af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org}
10293af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
10294af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1029532aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.orgCode* Code::FindFirstHandler() {
10296e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_inline_cache_stub());
1029779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
102984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
102994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  for (RelocIterator it(this, mask); !it.done(); it.next()) {
103004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    RelocInfo* info = it.rinfo();
1030132aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org    Code* code = Code::GetCodeFromTargetAddress(info->target_address());
1030232aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org    if (code->kind() == Code::HANDLER) return code;
103034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
103044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return NULL;
103054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
103064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
103074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
1030832aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.orgbool Code::FindHandlers(CodeHandleList* code_list, int length) {
10309e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_inline_cache_stub());
1031079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
103114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
103124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  int i = 0;
103134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  for (RelocIterator it(this, mask); !it.done(); it.next()) {
1031432aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org    if (i == length) return true;
103154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    RelocInfo* info = it.rinfo();
103164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Code* code = Code::GetCodeFromTargetAddress(info->target_address());
1031732aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org    // IC stubs with handlers never contain non-handler code objects before
1031832aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org    // handler targets.
1031932aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org    if (code->kind() != Code::HANDLER) break;
103204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    code_list->Add(Handle<Code>(code));
1032132aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org    i++;
103224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  }
1032332aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org  return i == length;
103244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
103254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
103264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
10327474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgMaybeHandle<Code> Code::FindHandlerForMap(Map* map) {
10328e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_inline_cache_stub());
10329474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
10330474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org             RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
10331474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  bool return_next = false;
10332474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  for (RelocIterator it(this, mask); !it.done(); it.next()) {
10333474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    RelocInfo* info = it.rinfo();
10334474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    if (info->rmode() == RelocInfo::EMBEDDED_OBJECT) {
10335474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      Object* object = info->target_object();
10336474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      if (object == map) return_next = true;
10337474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    } else if (return_next) {
10338474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      Code* code = Code::GetCodeFromTargetAddress(info->target_address());
10339e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(code->kind() == Code::HANDLER);
10340474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      return handle(code);
10341474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    }
10342474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  }
10343474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  return MaybeHandle<Code>();
10344474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org}
10345474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
10346474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
1034757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.orgName* Code::FindFirstName() {
10348e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_inline_cache_stub());
1034979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
1035057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
1035157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  for (RelocIterator it(this, mask); !it.done(); it.next()) {
1035257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    RelocInfo* info = it.rinfo();
1035357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    Object* object = info->target_object();
1035457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    if (object->IsName()) return Name::cast(object);
1035557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
1035657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  return NULL;
1035757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org}
1035857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
1035957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
103601456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid Code::ClearInlineCaches() {
10361e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  ClearInlineCaches(NULL);
10362e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org}
10363e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
10364e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
10365e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvoid Code::ClearInlineCaches(Code::Kind kind) {
10366e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  ClearInlineCaches(&kind);
10367e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org}
10368e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
10369e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
10370e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvoid Code::ClearInlineCaches(Code::Kind* kind) {
103711456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
103721456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org             RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) |
103739cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org             RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID);
103741456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  for (RelocIterator it(this, mask); !it.done(); it.next()) {
103751456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    RelocInfo* info = it.rinfo();
103761456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    Code* target(Code::GetCodeFromTargetAddress(info->target_address()));
103771456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    if (target->is_inline_cache_stub()) {
10378e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      if (kind == NULL || *kind == target->kind()) {
1037997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org        IC::Clear(this->GetIsolate(), info->pc(),
1038097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                  info->host()->constant_pool());
10381e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      }
103821456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    }
103831456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  }
103841456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}
103851456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
103861456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
10387a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgvoid SharedFunctionInfo::ClearTypeFeedbackInfo() {
10388a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  TypeFeedbackVector* vector = feedback_vector();
10389a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  Heap* heap = GetHeap();
103907e6132b924829c353864933f29124419916db550machenbach@chromium.org  int length = vector->length();
103917e6132b924829c353864933f29124419916db550machenbach@chromium.org
103927e6132b924829c353864933f29124419916db550machenbach@chromium.org  for (int i = 0; i < length; i++) {
10393a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    Object* obj = vector->get(i);
103947e6132b924829c353864933f29124419916db550machenbach@chromium.org    if (obj->IsHeapObject()) {
103957e6132b924829c353864933f29124419916db550machenbach@chromium.org      InstanceType instance_type =
103967e6132b924829c353864933f29124419916db550machenbach@chromium.org          HeapObject::cast(obj)->map()->instance_type();
103977e6132b924829c353864933f29124419916db550machenbach@chromium.org      switch (instance_type) {
103987e6132b924829c353864933f29124419916db550machenbach@chromium.org        case ALLOCATION_SITE_TYPE:
103997e6132b924829c353864933f29124419916db550machenbach@chromium.org          // AllocationSites are not cleared because they do not store
104007e6132b924829c353864933f29124419916db550machenbach@chromium.org          // information that leaks.
104017e6132b924829c353864933f29124419916db550machenbach@chromium.org          break;
104027e6132b924829c353864933f29124419916db550machenbach@chromium.org          // Fall through...
104037e6132b924829c353864933f29124419916db550machenbach@chromium.org        default:
10404a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org          vector->set(i, TypeFeedbackVector::RawUninitializedSentinel(heap),
104057e6132b924829c353864933f29124419916db550machenbach@chromium.org                      SKIP_WRITE_BARRIER);
104067e6132b924829c353864933f29124419916db550machenbach@chromium.org      }
10407212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    }
10408212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  }
10409212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org}
10410212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
10411212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
104123d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgBailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) {
104133d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  DisallowHeapAllocation no_gc;
10414e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kind() == FUNCTION);
10415528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  BackEdgeTable back_edges(this, &no_gc);
10416528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  for (uint32_t i = 0; i < back_edges.length(); i++) {
10417528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i);
104183d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  }
104193d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  return BailoutId::None();
104203d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org}
104213d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
104223d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
104234954674151afa960af66efb4831df06bde727333yangguo@chromium.orguint32_t Code::TranslateAstIdToPcOffset(BailoutId ast_id) {
104244954674151afa960af66efb4831df06bde727333yangguo@chromium.org  DisallowHeapAllocation no_gc;
10425e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(kind() == FUNCTION);
104264954674151afa960af66efb4831df06bde727333yangguo@chromium.org  BackEdgeTable back_edges(this, &no_gc);
104274954674151afa960af66efb4831df06bde727333yangguo@chromium.org  for (uint32_t i = 0; i < back_edges.length(); i++) {
104284954674151afa960af66efb4831df06bde727333yangguo@chromium.org    if (back_edges.ast_id(i) == ast_id) return back_edges.pc_offset(i);
104294954674151afa960af66efb4831df06bde727333yangguo@chromium.org  }
104304954674151afa960af66efb4831df06bde727333yangguo@chromium.org  UNREACHABLE();  // We expect to find the back edge.
104314954674151afa960af66efb4831df06bde727333yangguo@chromium.org  return 0;
104324954674151afa960af66efb4831df06bde727333yangguo@chromium.org}
104334954674151afa960af66efb4831df06bde727333yangguo@chromium.org
104344954674151afa960af66efb4831df06bde727333yangguo@chromium.org
10435528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) {
10436e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org  PatchPlatformCodeAge(isolate, sequence, kNoAgeCodeAge, NO_MARKING_PARITY);
10437e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
10438e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
10439e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
10440c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgvoid Code::MarkCodeAsExecuted(byte* sequence, Isolate* isolate) {
10441c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  PatchPlatformCodeAge(isolate, sequence, kExecutedOnceCodeAge,
10442c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      NO_MARKING_PARITY);
10443c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org}
10444c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
10445c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
10446057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgstatic Code::Age EffectiveAge(Code::Age age) {
10447057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  if (age == Code::kNotExecutedCodeAge) {
10448057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    // Treat that's never been executed as old immediately.
10449057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    age = Code::kIsOldCodeAge;
10450057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  } else if (age == Code::kExecutedOnceCodeAge) {
10451057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    // Pre-age code that has only been executed once.
10452057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    age = Code::kPreAgedCodeAge;
10453057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  }
10454057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  return age;
10455057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org}
10456057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
10457057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
10458e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid Code::MakeOlder(MarkingParity current_parity) {
10459e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  byte* sequence = FindCodeAgeSequence();
10460e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (sequence != NULL) {
10461e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    Age age;
10462e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    MarkingParity code_parity;
104635924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org    Isolate* isolate = GetIsolate();
104645924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org    GetCodeAgeAndParity(isolate, sequence, &age, &code_parity);
10465057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    age = EffectiveAge(age);
10466e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    if (age != kLastCodeAge && code_parity != current_parity) {
104675924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org      PatchPlatformCodeAge(isolate,
10468528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                           sequence,
10469528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                           static_cast<Age>(age + 1),
10470e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                           current_parity);
10471e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
10472e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
10473e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
10474e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
10475e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
10476e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgbool Code::IsOld() {
10477057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  return GetAge() >= kIsOldCodeAge;
10478e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
10479e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
10480e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
10481e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgbyte* Code::FindCodeAgeSequence() {
10482e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return FLAG_age_code &&
10483c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      prologue_offset() != Code::kPrologueOffsetNotSet &&
10484e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      (kind() == OPTIMIZED_FUNCTION ||
10485e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org       (kind() == FUNCTION && !has_debug_break_slots()))
1048683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      ? instruction_start() + prologue_offset()
10487e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      : NULL;
10488e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
10489e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
10490e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
10491c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgCode::Age Code::GetAge() {
10492057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  return EffectiveAge(GetRawAge());
10493057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org}
10494057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
10495057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
10496057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgCode::Age Code::GetRawAge() {
1049741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  byte* sequence = FindCodeAgeSequence();
1049841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (sequence == NULL) {
10499057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    return kNoAgeCodeAge;
1050041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
1050141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Age age;
1050241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  MarkingParity parity;
105035924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  GetCodeAgeAndParity(GetIsolate(), sequence, &age, &parity);
1050441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  return age;
1050541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
1050641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
1050741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
10508e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid Code::GetCodeAgeAndParity(Code* code, Age* age,
10509e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                               MarkingParity* parity) {
105103d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  Isolate* isolate = code->GetIsolate();
10511e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Builtins* builtins = isolate->builtins();
10512e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Code* stub = NULL;
10513e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org#define HANDLE_CODE_AGE(AGE)                                            \
10514e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  stub = *builtins->Make##AGE##CodeYoungAgainEvenMarking();             \
10515e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (code == stub) {                                                   \
10516e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    *age = k##AGE##CodeAge;                                             \
10517e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    *parity = EVEN_MARKING_PARITY;                                      \
10518e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    return;                                                             \
10519e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }                                                                     \
10520e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  stub = *builtins->Make##AGE##CodeYoungAgainOddMarking();              \
10521e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (code == stub) {                                                   \
10522e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    *age = k##AGE##CodeAge;                                             \
10523e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    *parity = ODD_MARKING_PARITY;                                       \
10524e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    return;                                                             \
10525e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
10526e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  CODE_AGE_LIST(HANDLE_CODE_AGE)
10527e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org#undef HANDLE_CODE_AGE
10528c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  stub = *builtins->MarkCodeAsExecutedOnce();
10529c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  if (code == stub) {
10530057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    *age = kNotExecutedCodeAge;
10531c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    *parity = NO_MARKING_PARITY;
10532c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    return;
10533c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  }
10534c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  stub = *builtins->MarkCodeAsExecutedTwice();
10535c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  if (code == stub) {
10536057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    *age = kExecutedOnceCodeAge;
10537c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    *parity = NO_MARKING_PARITY;
10538c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    return;
10539c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  }
10540e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  UNREACHABLE();
10541e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
10542e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
10543e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
10544528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgCode* Code::GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity) {
10545e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  Builtins* builtins = isolate->builtins();
10546e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  switch (age) {
10547e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org#define HANDLE_CODE_AGE(AGE)                                            \
10548e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    case k##AGE##CodeAge: {                                             \
10549e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      Code* stub = parity == EVEN_MARKING_PARITY                        \
10550e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org          ? *builtins->Make##AGE##CodeYoungAgainEvenMarking()           \
10551e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org          : *builtins->Make##AGE##CodeYoungAgainOddMarking();           \
10552e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      return stub;                                                      \
10553e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
10554e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    CODE_AGE_LIST(HANDLE_CODE_AGE)
10555e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org#undef HANDLE_CODE_AGE
10556c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    case kNotExecutedCodeAge: {
10557e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(parity == NO_MARKING_PARITY);
10558c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      return *builtins->MarkCodeAsExecutedOnce();
10559c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    }
10560c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    case kExecutedOnceCodeAge: {
10561e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(parity == NO_MARKING_PARITY);
10562c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      return *builtins->MarkCodeAsExecutedTwice();
10563c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    }
10564e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    default:
10565e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      UNREACHABLE();
10566e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      break;
10567e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
10568e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  return NULL;
10569e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
10570e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
10571e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
10572e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvoid Code::PrintDeoptLocation(FILE* out, int bailout_id) {
10573a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  const char* last_comment = NULL;
10574a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  int mask = RelocInfo::ModeMask(RelocInfo::COMMENT)
10575a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      | RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
10576a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  for (RelocIterator it(this, mask); !it.done(); it.next()) {
10577a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    RelocInfo* info = it.rinfo();
10578a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (info->rmode() == RelocInfo::COMMENT) {
10579a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      last_comment = reinterpret_cast<const char*>(info->data());
10580aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org    } else if (last_comment != NULL) {
10581aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org      if ((bailout_id == Deoptimizer::GetDeoptimizationId(
10582aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org              GetIsolate(), info->target_address(), Deoptimizer::EAGER)) ||
10583aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org          (bailout_id == Deoptimizer::GetDeoptimizationId(
10584d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org              GetIsolate(), info->target_address(), Deoptimizer::SOFT)) ||
10585d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org          (bailout_id == Deoptimizer::GetDeoptimizationId(
10586d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org              GetIsolate(), info->target_address(), Deoptimizer::LAZY))) {
10587aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org        CHECK(RelocInfo::IsRuntimeEntry(info->rmode()));
10588e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        PrintF(out, "            %s\n", last_comment);
10589aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org        return;
10590aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org      }
10591a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
10592a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
10593a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
10594a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
10595a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
10596c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgbool Code::CanDeoptAt(Address pc) {
10597c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  DeoptimizationInputData* deopt_data =
10598c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      DeoptimizationInputData::cast(deoptimization_data());
10599c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  Address code_start_address = instruction_start();
10600c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  for (int i = 0; i < deopt_data->DeoptCount(); i++) {
10601c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    if (deopt_data->Pc(i)->value() == -1) continue;
10602c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    Address address = code_start_address + deopt_data->Pc(i)->value();
10603c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    if (address == pc) return true;
10604c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  }
10605c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  return false;
10606c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org}
10607c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
10608c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
10609a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// Identify kind of code.
10610a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst char* Code::Kind2String(Kind kind) {
10611a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  switch (kind) {
106121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#define CASE(name) case name: return #name;
106131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    CODE_KIND_LIST(CASE)
106141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#undef CASE
106151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    case NUMBER_OF_KINDS: break;
10616a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
10617a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  UNREACHABLE();
10618a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return NULL;
10619a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
10620a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
10621a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
106224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#ifdef ENABLE_DISASSEMBLER
10623a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10624f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgvoid DeoptimizationInputData::DeoptimizationInputDataPrint(
10625f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    OStream& os) {  // NOLINT
10626a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  disasm::NameConverter converter;
10627a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int deopt_count = DeoptCount();
10628f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << "Deoptimization Input Data (deopt points = " << deopt_count << ")\n";
106297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (0 != deopt_count) {
106307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    os << " index  ast id    argc     pc";
1063131c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    if (FLAG_print_code_verbose) os << "  commands";
106327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    os << "\n";
106337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
10634a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < deopt_count; i++) {
10635f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    // TODO(svenpanne) Add some basic formatting to our streams.
10636f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    Vector<char> buf1 = Vector<char>::New(128);
10637f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    SNPrintF(buf1, "%6d  %6d  %6d %6d", i, AstId(i).ToInt(),
10638f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org             ArgumentsStackHeight(i)->value(), Pc(i)->value());
10639f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << buf1.start();
106407c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
106414acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    if (!FLAG_print_code_verbose) {
10642f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "\n";
106434acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org      continue;
106444acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    }
106457c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    // Print details of the frame translation.
10646a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    int translation_index = TranslationIndex(i)->value();
10647a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    TranslationIterator iterator(TranslationByteArray(), translation_index);
10648a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Translation::Opcode opcode =
10649a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        static_cast<Translation::Opcode>(iterator.Next());
10650e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(Translation::BEGIN == opcode);
10651a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    int frame_count = iterator.Next();
10652659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    int jsframe_count = iterator.Next();
10653f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "  " << Translation::StringFor(opcode)
10654f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org       << " {frame count=" << frame_count
10655f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org       << ", js frame count=" << jsframe_count << "}\n";
10656a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
106577c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    while (iterator.HasNext() &&
106587c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org           Translation::BEGIN !=
106597c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org           (opcode = static_cast<Translation::Opcode>(iterator.Next()))) {
10660f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      Vector<char> buf2 = Vector<char>::New(128);
1066131c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      SNPrintF(buf2, "%27s    %s ", "", Translation::StringFor(opcode));
10662f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << buf2.start();
10663a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
106647c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org      switch (opcode) {
106657c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        case Translation::BEGIN:
106667c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          UNREACHABLE();
106677c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          break;
106687c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
10669659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        case Translation::JS_FRAME: {
106707c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          int ast_id = iterator.Next();
106717c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          int function_id = iterator.Next();
106727c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          unsigned height = iterator.Next();
10673f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{ast_id=" << ast_id << ", function=";
106745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org          if (function_id != Translation::kSelfLiteralId) {
106755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org            Object* function = LiteralArray()->get(function_id);
10676f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org            os << Brief(JSFunction::cast(function)->shared()->DebugName());
106775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org          } else {
10678f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org            os << "<self>";
106795a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org          }
10680f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << ", height=" << height << "}";
106817c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          break;
10682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
10683659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
10684a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        case Translation::COMPILED_STUB_FRAME: {
10685a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          Code::Kind stub_kind = static_cast<Code::Kind>(iterator.Next());
10686f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{kind=" << stub_kind << "}";
10687a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          break;
10688a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        }
10689a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
10690967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org        case Translation::ARGUMENTS_ADAPTOR_FRAME:
10691967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org        case Translation::CONSTRUCT_STUB_FRAME: {
10692967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org          int function_id = iterator.Next();
10693967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org          JSFunction* function =
10694967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org              JSFunction::cast(LiteralArray()->get(function_id));
10695659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org          unsigned height = iterator.Next();
10696f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{function=" << Brief(function->shared()->DebugName())
10697f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org             << ", height=" << height << "}";
10698659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org          break;
10699659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        }
10700a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10701de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org        case Translation::GETTER_STUB_FRAME:
1070246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        case Translation::SETTER_STUB_FRAME: {
1070346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          int function_id = iterator.Next();
1070446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          JSFunction* function =
1070546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org              JSFunction::cast(LiteralArray()->get(function_id));
10706f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{function=" << Brief(function->shared()->DebugName()) << "}";
1070746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          break;
1070846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        }
1070946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
107107c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        case Translation::REGISTER: {
107117c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          int reg_code = iterator.Next();
10712f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{input=" << converter.NameOfCPURegister(reg_code) << "}";
107137c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          break;
107147c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        }
10715a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
107167c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        case Translation::INT32_REGISTER: {
107177c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          int reg_code = iterator.Next();
10718f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{input=" << converter.NameOfCPURegister(reg_code) << "}";
107197c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          break;
107207c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        }
10721a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1072246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        case Translation::UINT32_REGISTER: {
1072346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          int reg_code = iterator.Next();
10724f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{input=" << converter.NameOfCPURegister(reg_code)
10725f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org             << " (unsigned)}";
1072646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          break;
1072746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        }
1072846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
107297c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        case Translation::DOUBLE_REGISTER: {
107307c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          int reg_code = iterator.Next();
10731f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{input=" << DoubleRegister::AllocationIndexToString(reg_code)
10732f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org             << "}";
107337c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          break;
107347c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        }
10735a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
107367c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        case Translation::STACK_SLOT: {
107377c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          int input_slot_index = iterator.Next();
10738f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{input=" << input_slot_index << "}";
107397c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          break;
107407c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        }
10741a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
107427c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        case Translation::INT32_STACK_SLOT: {
107437c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          int input_slot_index = iterator.Next();
10744f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{input=" << input_slot_index << "}";
107457c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          break;
107467c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        }
10747a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1074846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        case Translation::UINT32_STACK_SLOT: {
1074946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          int input_slot_index = iterator.Next();
10750f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{input=" << input_slot_index << " (unsigned)}";
1075146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          break;
1075246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        }
1075346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
107547c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        case Translation::DOUBLE_STACK_SLOT: {
107557c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          int input_slot_index = iterator.Next();
10756f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{input=" << input_slot_index << "}";
107577c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          break;
107587c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        }
10759a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
107607c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org        case Translation::LITERAL: {
107617c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          unsigned literal_index = iterator.Next();
10762f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{literal_id=" << literal_index << "}";
107637c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          break;
10764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
107657c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
10766594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        case Translation::DUPLICATED_OBJECT: {
10767594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          int object_index = iterator.Next();
10768f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{object_index=" << object_index << "}";
10769594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          break;
10770594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        }
10771594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
10772594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        case Translation::ARGUMENTS_OBJECT:
10773594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        case Translation::CAPTURED_OBJECT: {
10774a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org          int args_length = iterator.Next();
10775f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          os << "{length=" << args_length << "}";
107767c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          break;
10777a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        }
10778a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
10779f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "\n";
10780a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
10781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
10782a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
10783a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10784a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10785f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgvoid DeoptimizationOutputData::DeoptimizationOutputDataPrint(
10786f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    OStream& os) {  // NOLINT
10787f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << "Deoptimization Output Data (deopt points = " << this->DeoptPoints()
10788f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org     << ")\n";
10789a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (this->DeoptPoints() == 0) return;
10790a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10791f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << "ast id        pc  state\n";
10792a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < this->DeoptPoints(); i++) {
10793a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    int pc_and_state = this->PcAndState(i)->value();
10794f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    // TODO(svenpanne) Add some basic formatting to our streams.
10795f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    Vector<char> buf = Vector<char>::New(100);
10796f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    SNPrintF(buf, "%6d  %8d  %s\n", this->AstId(i).ToInt(),
10797f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org             FullCodeGenerator::PcField::decode(pc_and_state),
10798f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org             FullCodeGenerator::State2String(
10799f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org                 FullCodeGenerator::StateField::decode(pc_and_state)));
10800f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << buf.start();
10801a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
10802a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
10803a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10804a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10805b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgconst char* Code::ICState2String(InlineCacheState state) {
10806b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  switch (state) {
10807b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org    case UNINITIALIZED: return "UNINITIALIZED";
10808b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org    case PREMONOMORPHIC: return "PREMONOMORPHIC";
10809b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org    case MONOMORPHIC: return "MONOMORPHIC";
10810474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    case PROTOTYPE_FAILURE:
10811474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      return "PROTOTYPE_FAILURE";
1081259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    case POLYMORPHIC: return "POLYMORPHIC";
10813b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org    case MEGAMORPHIC: return "MEGAMORPHIC";
1081446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    case GENERIC: return "GENERIC";
108159768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org    case DEBUG_STUB: return "DEBUG_STUB";
108168640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    case DEFAULT:
108178640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      return "DEFAULT";
10818b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  }
10819b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  UNREACHABLE();
10820b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  return NULL;
10821b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org}
10822b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org
10823b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org
108247a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.orgconst char* Code::StubType2String(StubType type) {
108252abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  switch (type) {
108262abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    case NORMAL: return "NORMAL";
108279af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org    case FAST: return "FAST";
108282abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  }
10829c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  UNREACHABLE();  // keep the compiler happy
108302abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  return NULL;
108312abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
108322abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
10833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10834f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgvoid Code::PrintExtraICState(OStream& os,  // NOLINT
10835f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org                             Kind kind, ExtraICState extra) {
10836f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << "extra_ic_state = ";
10837f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  if ((kind == STORE_IC || kind == KEYED_STORE_IC) && (extra == STRICT)) {
10838f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "STRICT\n";
10839496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  } else {
10840f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << extra << "\n";
10841496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  }
10842496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}
10843496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
10844496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
10845f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgvoid Code::Disassemble(const char* name, OStream& os) {  // NOLINT
10846f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << "kind = " << Kind2String(kind()) << "\n";
108479d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  if (IsCodeStubOrIC()) {
10848f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    const char* n = CodeStub::MajorName(CodeStub::GetMajorKey(this), true);
10849f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "major_key = " << (n == NULL ? "null" : n) << "\n";
1085090dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org  }
108512abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  if (is_inline_cache_stub()) {
10852f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "ic_state = " << ICState2String(ic_state()) << "\n";
10853f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    PrintExtraICState(os, kind(), extra_ic_state());
108542abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    if (ic_state() == MONOMORPHIC) {
10855f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "type = " << StubType2String(type()) << "\n";
108562abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org    }
108571044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org    if (is_compare_ic_stub()) {
10858e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(CodeStub::GetMajorKey(this) == CodeStub::CompareIC);
1085942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org      CompareICStub stub(stub_key(), GetIsolate());
10860d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org      os << "compare_state = " << CompareICState::GetStateName(stub.left())
10861d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org         << "*" << CompareICState::GetStateName(stub.right()) << " -> "
10862d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org         << CompareICState::GetStateName(stub.state()) << "\n";
1086321d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org      os << "compare_operation = " << Token::Name(stub.op()) << "\n";
10864212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    }
108652abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  }
108667be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  if ((name != NULL) && (name[0] != '\0')) {
10867f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "name = " << name << "\n";
108687be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  }
10869a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (kind() == OPTIMIZED_FUNCTION) {
10870f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "stack_slots = " << stack_slots() << "\n";
10871a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1087231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
10873f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << "Instructions (size = " << instruction_size() << ")\n";
10874f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  // TODO(svenpanne) The Disassembler should use streams, too!
10875c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org  {
10876c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org    CodeTracer::Scope trace_scope(GetIsolate()->GetCodeTracer());
10877c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org    Disassembler::Decode(trace_scope.file(), this);
10878c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org  }
10879f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << "\n";
1088031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
10881a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (kind() == FUNCTION) {
10882a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizationOutputData* data =
10883a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        DeoptimizationOutputData::cast(this->deoptimization_data());
10884f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    data->DeoptimizationOutputDataPrint(os);
10885a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (kind() == OPTIMIZED_FUNCTION) {
10886a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DeoptimizationInputData* data =
10887a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        DeoptimizationInputData::cast(this->deoptimization_data());
10888f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    data->DeoptimizationInputDataPrint(os);
10889a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
10890f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << "\n";
10891a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10892b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (is_crankshafted()) {
10893a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    SafepointTable table(this);
10894f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "Safepoints (size = " << table.size() << ")\n";
10895a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    for (unsigned i = 0; i < table.length(); i++) {
10896a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      unsigned pc_offset = table.GetPcOffset(i);
10897f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << (instruction_start() + pc_offset) << "  ";
10898f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      // TODO(svenpanne) Add some basic formatting to our streams.
10899f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      Vector<char> buf1 = Vector<char>::New(30);
10900f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      SNPrintF(buf1, "%4d", pc_offset);
10901f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << buf1.start() << "  ";
10902f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      table.PrintEntry(i, os);
10903f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << " (sp -> fp)  ";
10904c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      SafepointEntry entry = table.GetEntry(i);
10905c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      if (entry.deoptimization_index() != Safepoint::kNoDeoptimizationIndex) {
10906f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        Vector<char> buf2 = Vector<char>::New(30);
10907f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        SNPrintF(buf2, "%6d", entry.deoptimization_index());
10908f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << buf2.start();
10909a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      } else {
10910f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << "<none>";
10911a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
10912c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      if (entry.argument_count() > 0) {
10913f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << " argc: " << entry.argument_count();
10914c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org      }
10915f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "\n";
10916a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
10917f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    os << "\n";
10918a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (kind() == FUNCTION) {
10919e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    unsigned offset = back_edge_table_offset();
10920e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // If there is no back edge table, the "table start" will be at or after
10921a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // (due to alignment) the end of the instruction stream.
10922a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (static_cast<int>(offset) < instruction_size()) {
109233d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org      DisallowHeapAllocation no_gc;
10924528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      BackEdgeTable back_edges(this, &no_gc);
10925594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
10926f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "Back edges (size = " << back_edges.length() << ")\n";
10927f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "ast_id  pc_offset  loop_depth\n";
10928594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
10929528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      for (uint32_t i = 0; i < back_edges.length(); i++) {
10930f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        Vector<char> buf = Vector<char>::New(100);
10931f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        SNPrintF(buf, "%6d  %9u  %10u\n", back_edges.ast_id(i).ToInt(),
10932f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org                 back_edges.pc_offset(i), back_edges.loop_depth(i));
10933f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << buf.start();
10934a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
10935594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
10936f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "\n";
10937a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
10938000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org#ifdef OBJECT_PRINT
10939ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org    if (!type_feedback_info()->IsUndefined()) {
10940f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      OFStream os(stdout);
10941f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      TypeFeedbackInfo::cast(type_feedback_info())->TypeFeedbackInfoPrint(os);
10942f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "\n";
10943ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org    }
10944000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org#endif
10945a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
10946a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10947f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << "RelocInfo (size = " << relocation_size() << ")\n";
10948876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  for (RelocIterator it(this); !it.done(); it.next()) {
10949f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org    it.rinfo()->Print(GetIsolate(), os);
10950876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  }
10951f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  os << "\n";
1095231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager}
10953769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com#endif  // ENABLE_DISASSEMBLER
10954769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com
10955769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com
10956b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgHandle<FixedArray> JSObject::SetFastElementsCapacityAndLength(
10957b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<JSObject> object,
10958b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    int capacity,
10959b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    int length,
10960b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    SetFastElementsCapacitySmiMode smi_mode) {
109613811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // We should never end in here with a pixel or external array.
10962e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->HasExternalArrayElements());
1096340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
109647b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Allocate a new fast elements backing store.
109659b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  Handle<FixedArray> new_elements =
109669b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org      object->GetIsolate()->factory()->NewUninitializedFixedArray(capacity);
1096740b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
109689b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  ElementsKind elements_kind = object->GetElementsKind();
10969830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ElementsKind new_elements_kind;
10970830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it,
10971830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  // or if it's allowed and the old elements array contained only SMIs.
10972830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  bool has_fast_smi_elements =
10973830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      (smi_mode == kForceSmiElements) ||
109749b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org      ((smi_mode == kAllowSmiElements) && object->HasFastSmiElements());
10975830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (has_fast_smi_elements) {
10976830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    if (IsHoleyElementsKind(elements_kind)) {
10977830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      new_elements_kind = FAST_HOLEY_SMI_ELEMENTS;
10978830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    } else {
10979830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      new_elements_kind = FAST_SMI_ELEMENTS;
10980830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    }
10981830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  } else {
10982830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    if (IsHoleyElementsKind(elements_kind)) {
10983830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      new_elements_kind = FAST_HOLEY_ELEMENTS;
10984830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    } else {
10985830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      new_elements_kind = FAST_ELEMENTS;
10986830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    }
10987303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
109889b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  Handle<FixedArrayBase> old_elements(object->elements());
109894cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ElementsAccessor* accessor = ElementsAccessor::ForKind(new_elements_kind);
109909b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  accessor->CopyElements(object, new_elements, elements_kind);
1099183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
10992486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (elements_kind != SLOPPY_ARGUMENTS_ELEMENTS) {
109939b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    Handle<Map> new_map = (new_elements_kind != elements_kind)
109949b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org        ? GetElementsTransitionMap(object, new_elements_kind)
109959b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org        : handle(object->map());
1099649ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    JSObject::ValidateElements(object);
1099763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org    JSObject::SetMapAndElements(object, new_map, new_elements);
10998528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
10999528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // Transition through the allocation site as well if present.
110009b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    JSObject::UpdateAllocationSite(object, new_elements_kind);
110014efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  } else {
110029b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(old_elements);
110039b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    parameter_map->set(1, *new_elements);
1100443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1100540b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
11006394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_trace_elements_transitions) {
110079b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    PrintElementsTransition(stdout, object, elements_kind, old_elements,
110089b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org                            object->GetElementsKind(), new_elements);
11009394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
11010394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
110119b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  if (object->IsJSArray()) {
110129b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    Handle<JSArray>::cast(object)->set_length(Smi::FromInt(length));
1101340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  }
110147b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  return new_elements;
1101543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1101643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1101743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11018b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgvoid JSObject::SetFastDoubleElementsCapacityAndLength(Handle<JSObject> object,
11019b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                                      int capacity,
11020b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                                      int length) {
110216d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // We should never end in here with a pixel or external array.
11022e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->HasExternalArrayElements());
110236d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
110249b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  Handle<FixedArrayBase> elems =
110259b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org      object->GetIsolate()->factory()->NewFixedDoubleArray(capacity);
110266d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
110279b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  ElementsKind elements_kind = object->GetElementsKind();
110289b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  CHECK(elements_kind != SLOPPY_ARGUMENTS_ELEMENTS);
11029830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ElementsKind new_elements_kind = elements_kind;
11030830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (IsHoleyElementsKind(elements_kind)) {
11031830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    new_elements_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
11032830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  } else {
11033830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    new_elements_kind = FAST_DOUBLE_ELEMENTS;
11034830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  }
11035830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org
110369b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  Handle<Map> new_map = GetElementsTransitionMap(object, new_elements_kind);
110376d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
110389b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  Handle<FixedArrayBase> old_elements(object->elements());
110394cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ElementsAccessor* accessor = ElementsAccessor::ForKind(FAST_DOUBLE_ELEMENTS);
110409b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  accessor->CopyElements(object, elems, elements_kind);
110419b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org
1104249ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  JSObject::ValidateElements(object);
1104363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  JSObject::SetMapAndElements(object, new_map, elems);
110446d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
11045394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (FLAG_trace_elements_transitions) {
110469b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    PrintElementsTransition(stdout, object, elements_kind, old_elements,
110479b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org                            object->GetElementsKind(), elems);
11048394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
11049394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
110509b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  if (object->IsJSArray()) {
110519b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    Handle<JSArray>::cast(object)->set_length(Smi::FromInt(length));
110526d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
110536d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org}
110546d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
110556d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
110564452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org// static
110574452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.orgvoid JSArray::Initialize(Handle<JSArray> array, int capacity, int length) {
11058e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(capacity >= 0);
110594452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  array->GetIsolate()->factory()->NewJSArrayStorage(
110604452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org      array, length, capacity, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
1106143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1106243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1106343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11064b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.orgvoid JSArray::Expand(Handle<JSArray> array, int required_size) {
11065b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  ElementsAccessor* accessor = array->GetElementsAccessor();
11066b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  accessor->SetCapacityAndLength(array, required_size, required_size);
110677be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org}
110687be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
110697be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
110702f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org// Returns false if the passed-in index is marked non-configurable,
110712f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org// which will cause the ES5 truncation operation to halt, and thus
110722f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org// no further old values need be collected.
110732f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.orgstatic bool GetOldValue(Isolate* isolate,
110742f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org                        Handle<JSObject> object,
110752f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org                        uint32_t index,
110762f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org                        List<Handle<Object> >* old_values,
11077d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                        List<uint32_t>* indices) {
11078eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  Maybe<PropertyAttributes> maybe =
11079fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      JSReceiver::GetOwnElementAttribute(object, index);
11080e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(maybe.has_value);
11081e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(maybe.value != ABSENT);
11082eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  if (maybe.value == DONT_DELETE) return false;
110834452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  Handle<Object> value;
11084fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  if (!JSObject::GetOwnElementAccessorPair(object, index).is_null()) {
110854452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org    value = Handle<Object>::cast(isolate->factory()->the_hole_value());
110864452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  } else {
110872ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    value = Object::GetElement(isolate, object, index).ToHandleChecked();
110884452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  }
110894452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  old_values->Add(value);
11090d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  indices->Add(index);
110912f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  return true;
110922f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org}
110932f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org
11094d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgstatic void EnqueueSpliceRecord(Handle<JSArray> object,
11095d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                                uint32_t index,
11096d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                                Handle<JSArray> deleted,
11097d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                                uint32_t add_count) {
11098d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Isolate* isolate = object->GetIsolate();
11099d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HandleScope scope(isolate);
11100d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<Object> index_object = isolate->factory()->NewNumberFromUint(index);
11101d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<Object> add_count_object =
11102d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      isolate->factory()->NewNumberFromUint(add_count);
11103d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
11104d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<Object> args[] =
111051fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org      { object, index_object, deleted, add_count_object };
11106d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
111072c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  Execution::Call(isolate,
111082c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org                  Handle<JSFunction>(isolate->observers_enqueue_splice()),
111092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                  isolate->factory()->undefined_value(),
11110fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                  arraysize(args),
111112ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                  args).Assert();
11112d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
11113d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
11114d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
11115d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgstatic void BeginPerformSplice(Handle<JSArray> object) {
11116d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Isolate* isolate = object->GetIsolate();
11117d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HandleScope scope(isolate);
11118d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<Object> args[] = { object };
11119d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
111202c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  Execution::Call(isolate,
111212c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org                  Handle<JSFunction>(isolate->observers_begin_perform_splice()),
111222ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                  isolate->factory()->undefined_value(),
11123fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                  arraysize(args),
111242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                  args).Assert();
11125d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
11126d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
11127d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
11128d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgstatic void EndPerformSplice(Handle<JSArray> object) {
11129d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Isolate* isolate = object->GetIsolate();
11130d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HandleScope scope(isolate);
11131d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<Object> args[] = { object };
11132d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
111332c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  Execution::Call(isolate,
111342c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org                  Handle<JSFunction>(isolate->observers_end_perform_splice()),
111352ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                  isolate->factory()->undefined_value(),
11136fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                  arraysize(args),
111372ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                  args).Assert();
11138d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
11139d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
11140d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
111415b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgMaybeHandle<Object> JSArray::SetElementsLength(
111425b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    Handle<JSArray> array,
111435b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    Handle<Object> new_length_handle) {
111442b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org  if (array->HasFastElements()) {
111452b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org    // If the new array won't fit in a some non-trivial fraction of the max old
111462b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org    // space size, then force it to go dictionary mode.
111472b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org    int max_fast_array_size = static_cast<int>(
111482b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org        (array->GetHeap()->MaxOldGenerationSize() / kDoubleSize) / 4);
111492b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org    if (new_length_handle->IsNumber() &&
111502b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org        NumberToInt32(*new_length_handle) >= max_fast_array_size) {
111512b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org      NormalizeElements(array);
111522b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org    }
111532b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org  }
111542b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org
111553811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // We should never end in here with a pixel or external array.
11156e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(array->AllowsSetElementsLength());
1115769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  if (!array->map()->is_observed()) {
1115869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    return array->GetElementsAccessor()->SetLength(array, new_length_handle);
1115969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  }
11160fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
1116169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  Isolate* isolate = array->GetIsolate();
11162d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  List<uint32_t> indices;
11163fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  List<Handle<Object> > old_values;
1116469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  Handle<Object> old_length_handle(array->length(), isolate);
11165fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  uint32_t old_length = 0;
11166fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  CHECK(old_length_handle->ToArrayIndex(&old_length));
11167fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  uint32_t new_length = 0;
1116869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  CHECK(new_length_handle->ToArrayIndex(&new_length));
11169fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
111702f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  static const PropertyAttributes kNoAttrFilter = NONE;
11171fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  int num_elements = array->NumberOfOwnElements(kNoAttrFilter);
111722f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  if (num_elements > 0) {
111732f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org    if (old_length == static_cast<uint32_t>(num_elements)) {
111742f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      // Simple case for arrays without holes.
111752f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      for (uint32_t i = old_length - 1; i + 1 > new_length; --i) {
1117669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        if (!GetOldValue(isolate, array, i, &old_values, &indices)) break;
111772f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      }
111782f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org    } else {
111792f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      // For sparse arrays, only iterate over existing elements.
11180b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over
11181b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      // the to-be-removed indices twice.
111822f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements);
11183fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      array->GetOwnElementKeys(*keys, kNoAttrFilter);
111842f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      while (num_elements-- > 0) {
111852f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org        uint32_t index = NumberToUint32(keys->get(num_elements));
111862f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org        if (index < new_length) break;
1118769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        if (!GetOldValue(isolate, array, index, &old_values, &indices)) break;
111882f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      }
111892f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org    }
11190fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
11191fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
111925b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  Handle<Object> hresult;
111935b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
111945b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      isolate, hresult,
111955b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      array->GetElementsAccessor()->SetLength(array, new_length_handle),
111965b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      Object);
11197fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
1119869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  CHECK(array->length()->ToArrayIndex(&new_length));
1119969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  if (old_length == new_length) return hresult;
11200d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1120169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  BeginPerformSplice(array);
11202d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
11203d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  for (int i = 0; i < indices.length(); ++i) {
11204c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org    // For deletions where the property was an accessor, old_values[i]
11205c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org    // will be the hole, which instructs EnqueueChangeRecord to elide
11206c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org    // the "oldValue" property.
11207fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    JSObject::EnqueueChangeRecord(
1120869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        array, "delete", isolate->factory()->Uint32ToString(indices[i]),
11209d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org        old_values[i]);
11210d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
11211d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  JSObject::EnqueueChangeRecord(
1121269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org      array, "update", isolate->factory()->length_string(),
11213d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      old_length_handle);
11214d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1121569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  EndPerformSplice(array);
11216d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
11217d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  uint32_t index = Min(old_length, new_length);
11218d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  uint32_t add_count = new_length > old_length ? new_length - old_length : 0;
11219d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  uint32_t delete_count = new_length < old_length ? old_length - new_length : 0;
11220d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
112211fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  if (delete_count > 0) {
11222d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    for (int i = indices.length() - 1; i >= 0; i--) {
11223c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org      // Skip deletions where the property was an accessor, leaving holes
11224c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org      // in the array of old values.
11225c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org      if (old_values[i]->IsTheHole()) continue;
112269e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      JSObject::SetElement(
112279e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org          deleted, indices[i] - index, old_values[i], NONE, SLOPPY).Assert();
11228d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    }
112291fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
112301fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    SetProperty(deleted, isolate->factory()->length_string(),
112311fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                isolate->factory()->NewNumberFromUint(delete_count),
112329bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                STRICT).Assert();
11233fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
11234d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1123569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  EnqueueSpliceRecord(array, index, deleted, add_count);
11236d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1123769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  return hresult;
1123843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1123943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1124043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11241c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgHandle<Map> Map::GetPrototypeTransition(Handle<Map> map,
11242c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org                                        Handle<Object> prototype) {
11243c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  FixedArray* cache = map->GetPrototypeTransitions();
11244c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  int number_of_transitions = map->NumberOfProtoTransitions();
11245d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  const int proto_offset =
11246d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com      kProtoTransitionHeaderSize + kProtoTransitionPrototypeOffset;
11247d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  const int map_offset = kProtoTransitionHeaderSize + kProtoTransitionMapOffset;
11248d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  const int step = kProtoTransitionElementsPerEntry;
11249d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  for (int i = 0; i < number_of_transitions; i++) {
11250c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    if (cache->get(proto_offset + i * step) == *prototype) {
11251c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      Object* result = cache->get(map_offset + i * step);
11252c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      return Handle<Map>(Map::cast(result));
11253d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com    }
112543847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  }
11255c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  return Handle<Map>();
112563847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com}
112573847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
112583847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
11259c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgHandle<Map> Map::PutPrototypeTransition(Handle<Map> map,
11260c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org                                        Handle<Object> prototype,
11261c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org                                        Handle<Map> target_map) {
11262e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(target_map->IsMap());
11263e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(HeapObject::cast(*prototype)->map()->IsMap());
11264e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  // Don't cache prototype transition if this map is either shared, or a map of
11265e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  // a prototype.
11266e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  if (map->is_prototype_map()) return map;
1126731c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  if (map->is_dictionary_map() || !FLAG_cache_prototype_transitions) return map;
112683847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
11269d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  const int step = kProtoTransitionElementsPerEntry;
11270d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  const int header = kProtoTransitionHeaderSize;
11271d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
11272c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  Handle<FixedArray> cache(map->GetPrototypeTransitions());
11273d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  int capacity = (cache->length() - header) / step;
11274c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  int transitions = map->NumberOfProtoTransitions() + 1;
112753847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
11276d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  if (transitions > capacity) {
11277c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    if (capacity > kMaxCachedPrototypeTransitions) return map;
112783847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
11279d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com    // Grow array by factor 2 over and above what we need.
112803484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    cache = FixedArray::CopySize(cache, transitions * 2 * step + header);
112813847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
11282c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    SetPrototypeTransitions(map, cache);
112833847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  }
112843847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
11285c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  // Reload number of transitions as GC might shrink them.
11286c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  int last = map->NumberOfProtoTransitions();
11287c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  int entry = header + last * step;
11288d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
11289c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  cache->set(entry + kProtoTransitionPrototypeOffset, *prototype);
11290c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  cache->set(entry + kProtoTransitionMapOffset, *target_map);
11291e5c3b69d269a0509fe309cba296dd71414f5a715hpayer@chromium.org  map->SetNumberOfProtoTransitions(last + 1);
112923847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
11293c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  return map;
112943847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com}
112953847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
112963847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
11297c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid Map::ZapTransitions() {
11298c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  TransitionArray* transition_array = transitions();
11299f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // TODO(mstarzinger): Temporarily use a slower version instead of the faster
11300f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // MemsetPointer to investigate a crasher. Switch back to MemsetPointer.
11301f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Object** data = transition_array->data_start();
11302f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Object* the_hole = GetHeap()->the_hole_value();
11303f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  int length = transition_array->length();
11304f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  for (int i = 0; i < length; i++) {
11305f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    data[i] = the_hole;
11306f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
11307c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org}
11308c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
11309c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
11310c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid Map::ZapPrototypeTransitions() {
11311c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  FixedArray* proto_transitions = GetPrototypeTransitions();
11312c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  MemsetPointer(proto_transitions->data_start(),
11313c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org                GetHeap()->the_hole_value(),
11314c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org                proto_transitions->length());
11315c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org}
11316c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
11317c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
11318e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org// static
11319e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgvoid Map::AddDependentCompilationInfo(Handle<Map> map,
11320e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                      DependentCode::DependencyGroup group,
1132141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                                      CompilationInfo* info) {
1132241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Handle<DependentCode> codes =
11323e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      DependentCode::Insert(handle(map->dependent_code(), info->isolate()),
11324e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                            group, info->object_wrapper());
11325e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (*codes != map->dependent_code()) map->set_dependent_code(*codes);
11326e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  info->dependencies(group)->Add(map, info->zone());
1132741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
1132841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
1132941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
11330e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org// static
11331e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgvoid Map::AddDependentCode(Handle<Map> map,
11332e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                           DependentCode::DependencyGroup group,
1133341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                           Handle<Code> code) {
1133441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Handle<DependentCode> codes = DependentCode::Insert(
11335e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      Handle<DependentCode>(map->dependent_code()), group, code);
11336e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (*codes != map->dependent_code()) map->set_dependent_code(*codes);
1133741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
1133841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
1133941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
11340e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org// static
11341e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgvoid Map::AddDependentIC(Handle<Map> map,
11342e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                         Handle<Code> stub) {
11343e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(stub->next_code_link()->IsUndefined());
11344e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  int n = map->dependent_code()->number_of_entries(DependentCode::kWeakICGroup);
113452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (n == 0) {
113462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    // Slow path: insert the head of the list with possible heap allocation.
11347e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Map::AddDependentCode(map, DependentCode::kWeakICGroup, stub);
113482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  } else {
113492ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    // Fast path: link the stub to the existing head of the list without any
113502ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    // heap allocation.
11351e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(n == 1);
11352e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    map->dependent_code()->AddToDependentICList(stub);
113532ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
113542ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org}
113552ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
113562ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
113572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgDependentCode::GroupStartIndexes::GroupStartIndexes(DependentCode* entries) {
113582e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  Recompute(entries);
113592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org}
113602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
113612e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
113622e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgvoid DependentCode::GroupStartIndexes::Recompute(DependentCode* entries) {
113632e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  start_indexes_[0] = 0;
113642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  for (int g = 1; g <= kGroupCount; g++) {
113652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    int count = entries->number_of_entries(static_cast<DependencyGroup>(g - 1));
113662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    start_indexes_[g] = start_indexes_[g - 1] + count;
113672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
113682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org}
113692e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
113702e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
113711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDependentCode* DependentCode::ForObject(Handle<HeapObject> object,
113721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                        DependencyGroup group) {
113731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  AllowDeferredHandleDereference dependencies_are_safe;
113741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (group == DependentCode::kPropertyCellChangedGroup) {
113751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return Handle<PropertyCell>::cast(object)->dependent_code();
11376b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  } else if (group == DependentCode::kAllocationSiteTenuringChangedGroup ||
11377b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      group == DependentCode::kAllocationSiteTransitionChangedGroup) {
11378b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    return Handle<AllocationSite>::cast(object)->dependent_code();
113791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
113801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return Handle<Map>::cast(object)->dependent_code();
113811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
113821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
113831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
113842e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgHandle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries,
113852e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                            DependencyGroup group,
1138641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                                            Handle<Object> object) {
113872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  GroupStartIndexes starts(*entries);
113882e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int start = starts.at(group);
113892e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int end = starts.at(group + 1);
113902e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int number_of_entries = starts.number_of_entries();
11391b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // Check for existing entry to avoid duplicates.
11392b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  for (int i = start; i < end; i++) {
11393b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (entries->object_at(i) == *object) return entries;
11394003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
113952e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (entries->length() < kCodesStartIndex + number_of_entries + 1) {
113962e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    int capacity = kCodesStartIndex + number_of_entries + 1;
11397003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    if (capacity > 5) capacity = capacity * 5 / 4;
113982e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    Handle<DependentCode> new_entries = Handle<DependentCode>::cast(
113993484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org        FixedArray::CopySize(entries, capacity, TENURED));
11400003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    // The number of codes can change after GC.
114012e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    starts.Recompute(*entries);
114022e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    start = starts.at(group);
114032e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    end = starts.at(group + 1);
114042e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    number_of_entries = starts.number_of_entries();
114052e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    for (int i = 0; i < number_of_entries; i++) {
1140641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      entries->clear_at(i);
114072e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
114082e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // If the old fixed array was empty, we need to reset counters of the
114092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // new array.
114102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (number_of_entries == 0) {
114112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      for (int g = 0; g < kGroupCount; g++) {
114122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        new_entries->set_number_of_entries(static_cast<DependencyGroup>(g), 0);
114132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      }
11414003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    }
114152e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    entries = new_entries;
11416003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
114172e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  entries->ExtendGroup(group);
1141841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  entries->set_object_at(end, *object);
114192e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  entries->set_number_of_entries(group, end + 1 - start);
114202e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  return entries;
11421003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
11422003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
11423003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
1142441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgvoid DependentCode::UpdateToFinishedCode(DependencyGroup group,
1142541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                                         CompilationInfo* info,
1142641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                                         Code* code) {
1142741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  DisallowHeapAllocation no_gc;
1142841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  AllowDeferredHandleDereference get_object_wrapper;
1142941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Foreign* info_wrapper = *info->object_wrapper();
1143041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  GroupStartIndexes starts(this);
1143141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  int start = starts.at(group);
1143241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  int end = starts.at(group + 1);
1143341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  for (int i = start; i < end; i++) {
1143441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    if (object_at(i) == info_wrapper) {
1143541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      set_object_at(i, code);
1143641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      break;
1143741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    }
1143841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
1143941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
1144041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org#ifdef DEBUG
1144141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  for (int i = start; i < end; i++) {
11442e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_code_at(i) || compilation_info_at(i) != info);
1144341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
1144441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org#endif
1144541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
1144641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
1144741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
1144841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgvoid DependentCode::RemoveCompilationInfo(DependentCode::DependencyGroup group,
1144941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                                          CompilationInfo* info) {
1145041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  DisallowHeapAllocation no_allocation;
1145141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  AllowDeferredHandleDereference get_object_wrapper;
1145241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Foreign* info_wrapper = *info->object_wrapper();
1145341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  GroupStartIndexes starts(this);
1145441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  int start = starts.at(group);
1145541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  int end = starts.at(group + 1);
1145641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  // Find compilation info wrapper.
1145741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  int info_pos = -1;
1145841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  for (int i = start; i < end; i++) {
1145941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    if (object_at(i) == info_wrapper) {
1146041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      info_pos = i;
1146141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      break;
1146241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    }
1146341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
1146441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (info_pos == -1) return;  // Not found.
1146541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  int gap = info_pos;
1146641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  // Use the last of each group to fill the gap in the previous group.
1146741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  for (int i = group; i < kGroupCount; i++) {
1146841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    int last_of_group = starts.at(i + 1) - 1;
11469e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(last_of_group >= gap);
1147041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    if (last_of_group == gap) continue;
1147141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    copy(last_of_group, gap);
1147241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    gap = last_of_group;
1147341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
11474e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(gap == starts.number_of_entries() - 1);
1147541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  clear_at(gap);  // Clear last gap.
1147641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  set_number_of_entries(group, end - start - 1);
1147741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
1147841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org#ifdef DEBUG
1147941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  for (int i = start; i < end - 1; i++) {
11480e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(is_code_at(i) || compilation_info_at(i) != info);
1148141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
1148241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org#endif
1148341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
1148441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
1148541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
114862ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgstatic bool CodeListContains(Object* head, Code* code) {
114872ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  while (!head->IsUndefined()) {
114882ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (head == code) return true;
114892ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    head = Code::cast(head)->next_code_link();
114902ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
114912ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return false;
114922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org}
114932ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
114942ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
114952e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgbool DependentCode::Contains(DependencyGroup group, Code* code) {
114962e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  GroupStartIndexes starts(this);
11497c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  int start = starts.at(group);
11498c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  int end = starts.at(group + 1);
114992ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (group == kWeakICGroup) {
115002ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    return CodeListContains(object_at(start), code);
115012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
11502c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  for (int i = start; i < end; i++) {
1150341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    if (object_at(i) == code) return true;
1150494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  }
1150594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  return false;
1150694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
1150794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
1150894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
115095c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.orgbool DependentCode::MarkCodeForDeoptimization(
11510876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    Isolate* isolate,
115112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    DependentCode::DependencyGroup group) {
1151279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation_scope;
115132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  DependentCode::GroupStartIndexes starts(this);
115142e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int start = starts.at(group);
115152e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int end = starts.at(group + 1);
1151641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  int code_entries = starts.number_of_entries();
115175c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  if (start == end) return false;
11518fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
115193d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  // Mark all the code that needs to be deoptimized.
115203d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  bool marked = false;
115212e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  for (int i = start; i < end; i++) {
11522f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (is_code_at(i)) {
11523f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      Code* code = code_at(i);
115243d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org      if (!code->marked_for_deoptimization()) {
115255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        SetMarkedForDeoptimization(code, group);
115263d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org        marked = true;
115273d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org      }
1152841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    } else {
11529f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      CompilationInfo* info = compilation_info_at(i);
115301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      info->AbortDueToDependencyChange();
1153141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    }
115322e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
1153309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  // Compact the array by moving all subsequent groups to fill in the new holes.
1153441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  for (int src = end, dst = start; src < code_entries; src++, dst++) {
1153541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    copy(src, dst);
115362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
1153709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  // Now the holes are at the end of the array, zap them for heap-verifier.
1153809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  int removed = end - start;
1153941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  for (int i = code_entries - removed; i < code_entries; i++) {
1154041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    clear_at(i);
1154109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  }
115422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  set_number_of_entries(group, 0);
115435c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  return marked;
115445c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org}
115455c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
115465c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org
115475c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.orgvoid DependentCode::DeoptimizeDependentCodeGroup(
115485c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    Isolate* isolate,
115495c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    DependentCode::DependencyGroup group) {
11550e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(AllowCodeDependencyChange::IsAllowed());
115515c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  DisallowHeapAllocation no_allocation_scope;
115525c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  bool marked = MarkCodeForDeoptimization(isolate, group);
115533d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
115543d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  if (marked) Deoptimizer::DeoptimizeMarkedCode(isolate);
115552e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org}
115562e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
115572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
115582ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgvoid DependentCode::AddToDependentICList(Handle<Code> stub) {
115592ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  DisallowHeapAllocation no_heap_allocation;
115602ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  GroupStartIndexes starts(this);
115612ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int i = starts.at(kWeakICGroup);
115623ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  Object* head = object_at(i);
115633ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  // Try to insert the stub after the head of the list to minimize number of
115643ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  // writes to the DependentCode array, since a write to the array can make it
115653ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  // strong if it was alread marked by incremental marker.
115663ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  if (head->IsCode()) {
115673ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    stub->set_next_code_link(Code::cast(head)->next_code_link());
115683ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    Code::cast(head)->set_next_code_link(*stub);
115693ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  } else {
115703ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    stub->set_next_code_link(head);
115713ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    set_object_at(i, *stub);
115723ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  }
115732ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org}
115742ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
115752ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
115765e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid DependentCode::SetMarkedForDeoptimization(Code* code,
115775e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                                               DependencyGroup group) {
115785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  code->set_marked_for_deoptimization(true);
115795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  if (FLAG_trace_deopt &&
115805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      (code->deoptimization_data() != code->GetHeap()->empty_fixed_array())) {
115815e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    DeoptimizationInputData* deopt_data =
115825e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        DeoptimizationInputData::cast(code->deoptimization_data());
115835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer());
115845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    PrintF(scope.file(), "[marking dependent code 0x%08" V8PRIxPTR
115855e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                         " (opt #%d) for deoptimization, reason: %s]\n",
115865e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org           reinterpret_cast<intptr_t>(code),
115875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org           deopt_data->OptimizationId()->value(), DependencyGroupName(group));
115885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  }
115895e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
115905e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
115915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
115925e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgconst char* DependentCode::DependencyGroupName(DependencyGroup group) {
115935e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  switch (group) {
115945e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kWeakICGroup:
115955e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return "weak-ic";
115965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kWeakCodeGroup:
115975e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return "weak-code";
115985e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kTransitionGroup:
115995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return "transition";
116005e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kPrototypeCheckGroup:
116015e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return "prototype-check";
116025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kElementsCantBeAddedGroup:
116035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return "elements-cant-be-added";
116045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kPropertyCellChangedGroup:
116055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return "property-cell-changed";
116065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kFieldTypeGroup:
116075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return "field-type";
116085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kInitialMapChangedGroup:
116095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return "initial-map-changed";
116105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kAllocationSiteTenuringChangedGroup:
116115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return "allocation-site-tenuring-changed";
116125e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kAllocationSiteTransitionChangedGroup:
116135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return "allocation-site-transition-changed";
116145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  }
116156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  UNREACHABLE();
116166474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  return "?";
116175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
116185e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
116195e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
11620c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgHandle<Map> Map::TransitionToPrototype(Handle<Map> map,
11621c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                                       Handle<Object> prototype) {
11622c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  Handle<Map> new_map = GetPrototypeTransition(map, prototype);
11623c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  if (new_map.is_null()) {
11624c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    new_map = Copy(map);
11625c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    PutPrototypeTransition(map, prototype, new_map);
11626c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    new_map->set_prototype(*prototype);
11627c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  }
11628c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  return new_map;
11629c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org}
11630c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
11631c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
11632a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
11633a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org                                           Handle<Object> value,
1163431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org                                           bool from_javascript) {
11635d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com#ifdef DEBUG
11636c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  int size = object->Size();
11637d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com#endif
11638d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
11639c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
116408432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Heap* heap = isolate->heap();
116415c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Silently ignore the change if value is not a JSObject or null.
116425c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // SpiderMonkey behaves this way.
11643d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  if (!value->IsJSReceiver() && !value->IsNull()) return value;
116445c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1164544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // From 8.6.2 Object Internal Methods
1164644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // ...
1164744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // In addition, if [[Extensible]] is false the value of the [[Class]] and
1164844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // [[Prototype]] internal properties of the object may not be modified.
1164944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // ...
1165044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // Implementation specific extensions that modify [[Class]], [[Prototype]]
1165144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // or [[Extensible]] must not violate the invariants defined in the preceding
1165244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // paragraph.
11653c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  if (!object->map()->is_extensible()) {
11654c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    Handle<Object> args[] = { object };
11655ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    THROW_NEW_ERROR(isolate, NewTypeError("non_extensible_proto",
11656ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                          HandleVector(args, arraysize(args))),
11657ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                    Object);
1165844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  }
1165944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
116605c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Before we can set the prototype we need to be sure
116615c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // prototype cycles are prevented.
116625c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // It is sufficient to validate that the receiver is not in the new prototype
116635c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // chain.
116649bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  for (PrototypeIterator iter(isolate, *value,
116659bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                              PrototypeIterator::START_AT_RECEIVER);
116669bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org       !iter.IsAtEnd(); iter.Advance()) {
116679bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    if (JSReceiver::cast(iter.GetCurrent()) == *object) {
116685c838251403b0be9a882540f1922577abba4c872ager@chromium.org      // Cycle detected.
11669ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      THROW_NEW_ERROR(isolate,
11670ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                      NewError("cyclic_proto", HandleVector<Object>(NULL, 0)),
11671ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                      Object);
116725c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
116735c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
116745c838251403b0be9a882540f1922577abba4c872ager@chromium.org
11675e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  bool dictionary_elements_in_chain =
11676e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      object->map()->DictionaryElementsInPrototypeChainOnly();
11677c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  Handle<JSObject> real_receiver = object;
116785c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1167931c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  if (from_javascript) {
116805c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Find the first object in the chain whose prototype object is not
116815c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // hidden and set the new prototype on that object.
116829bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    PrototypeIterator iter(isolate, real_receiver);
116839bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
116849bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org      real_receiver =
116859bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
116869bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org      iter.Advance();
116875c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
116885c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
116895c838251403b0be9a882540f1922577abba4c872ager@chromium.org
116905c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Set the new prototype of the object.
11691c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  Handle<Map> map(real_receiver->map());
116923847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
116933847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  // Nothing to do if prototype is already set.
11694c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  if (map->prototype() == *value) return value;
116953847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
116967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  if (value->IsJSObject()) {
1169731c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    PrototypeOptimizationMode mode =
1169831c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org        from_javascript ? REGULAR_PROTOTYPE : FAST_PROTOTYPE;
1169931c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org    JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value), mode);
117007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
117017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
11702c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  Handle<Map> new_map = Map::TransitionToPrototype(map, value);
11703e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(new_map->prototype() == *value);
1170497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  JSObject::MigrateToMap(real_receiver, new_map);
117055c838251403b0be9a882540f1922577abba4c872ager@chromium.org
11706e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  if (!dictionary_elements_in_chain &&
11707e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      new_map->DictionaryElementsInPrototypeChainOnly()) {
11708e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    // If the prototype chain didn't previously have element callbacks, then
11709e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    // KeyedStoreICs need to be cleared to ensure any that involve this
11710e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    // map go generic.
11711e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    object->GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC);
11712e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  }
11713e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
11714ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  heap->ClearInstanceofCache();
11715e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(size == object->Size());
117165c838251403b0be9a882540f1922577abba4c872ager@chromium.org  return value;
117175c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
117185c838251403b0be9a882540f1922577abba4c872ager@chromium.org
117195c838251403b0be9a882540f1922577abba4c872ager@chromium.org
117204452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.orgvoid JSObject::EnsureCanContainElements(Handle<JSObject> object,
117214452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org                                        Arguments* args,
117224452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org                                        uint32_t first_arg,
117234452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org                                        uint32_t arg_count,
117244452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org                                        EnsureElementsMode mode) {
11725c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Elements in |Arguments| are ordered backwards (because they're on the
11726c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // stack), but the method that's called here iterates over them in forward
11727c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // direction.
11728c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return EnsureCanContainElements(
11729a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org      object, args->arguments() - first_arg - (arg_count - 1), arg_count, mode);
11730c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
11731c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
11732c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
11733fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgMaybeHandle<AccessorPair> JSObject::GetOwnElementAccessorPair(
1173449ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    Handle<JSObject> object,
1173549ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    uint32_t index) {
1173649ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  if (object->IsJSGlobalProxy()) {
1173793720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    PrototypeIterator iter(object->GetIsolate(), object);
1173893720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    if (iter.IsAtEnd()) return MaybeHandle<AccessorPair>();
11739e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
1174093720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    return GetOwnElementAccessorPair(
1174193720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index);
11742f4f9499877ee748c6caf1d4fd7d845bf4f825e00mstarzinger@chromium.org  }
11743f4f9499877ee748c6caf1d4fd7d845bf4f825e00mstarzinger@chromium.org
117448e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // Check for lookup interceptor.
1174549ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  if (object->HasIndexedInterceptor()) return MaybeHandle<AccessorPair>();
11746f4f9499877ee748c6caf1d4fd7d845bf4f825e00mstarzinger@chromium.org
1174749ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org  return object->GetElementsAccessor()->GetAccessorPair(object, object, index);
1174843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1174943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1175043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117519e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSObject::SetElementWithInterceptor(
11752b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<JSObject> object,
11753b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    uint32_t index,
11754b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<Object> value,
11755b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    PropertyAttributes attributes,
11756486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    StrictMode strict_mode,
11757b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    bool check_prototype,
11758b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    SetPropertyMode set_mode) {
11759b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
11760dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
1176143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make sure that the top context does not change when doing
1176243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // callbacks or interceptor calls.
11763fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  AssertNoContextChange ncc(isolate);
11764dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
11765b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
1176643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!interceptor->setter()->IsUndefined()) {
11767662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    v8::IndexedPropertySetterCallback setter =
11768662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org        v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter());
11769ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    LOG(isolate,
11770b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        ApiIndexedPropertyAccess("interceptor-indexed-set", *object, index));
11771b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    PropertyCallbackArguments args(isolate, interceptor->data(), *object,
11772b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                   *object);
117731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    v8::Handle<v8::Value> result =
11774b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        args.Call(setter, index, v8::Utils::ToLocal(value));
117759e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
11776b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (!result.IsEmpty()) return value;
11777b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
11778b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
11779b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  return SetElementWithoutInterceptor(object, index, value, attributes,
11780b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                      strict_mode,
11781b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                      check_prototype,
11782b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                      set_mode);
1178343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1178443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1178543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11786202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.orgMaybeHandle<Object> JSObject::GetElementWithCallback(
117879e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Handle<JSObject> object,
117889e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Handle<Object> receiver,
117899e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Handle<Object> structure,
117909e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    uint32_t index,
117919e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Handle<Object> holder) {
11792202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
11793e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!structure->IsForeign());
117949155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // api style callbacks.
117957c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  if (structure->IsExecutableAccessorInfo()) {
11796202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    Handle<ExecutableAccessorInfo> data =
11797202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        Handle<ExecutableAccessorInfo>::cast(structure);
117989155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    Object* fun_obj = data->getter();
11799e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    v8::AccessorNameGetterCallback call_fun =
11800e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        v8::ToCData<v8::AccessorNameGetterCallback>(fun_obj);
11801202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    if (call_fun == NULL) return isolate->factory()->undefined_value();
11802202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    Handle<JSObject> holder_handle = Handle<JSObject>::cast(holder);
11803ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
118047b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    Handle<String> key = isolate->factory()->NumberToString(number);
11805731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    LOG(isolate, ApiNamedPropertyAccess("load", *holder_handle, *key));
11806bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    PropertyCallbackArguments
11807731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        args(isolate, data->data(), *receiver, *holder_handle);
118081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    v8::Handle<v8::Value> result = args.Call(call_fun, v8::Utils::ToLocal(key));
11809202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
11810202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    if (result.IsEmpty()) return isolate->factory()->undefined_value();
11811de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
11812de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    result_internal->VerifyApiCallResultType();
11813202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    // Rebox handle before return.
11814202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    return handle(*result_internal, isolate);
118159155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  }
118169155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
118179155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // __defineGetter__ callback
11818f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (structure->IsAccessorPair()) {
11819202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    Handle<Object> getter(Handle<AccessorPair>::cast(structure)->getter(),
11820202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org                          isolate);
11821c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (getter->IsSpecFunction()) {
11822c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // TODO(rossberg): nicer would be to cast to some JSCallable here...
11823202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      return GetPropertyWithDefinedGetter(
11824e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org          receiver, Handle<JSReceiver>::cast(getter));
118259155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    }
118269155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    // Getter is not a function.
11827202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    return isolate->factory()->undefined_value();
118289155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  }
118299155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
118307c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  if (structure->IsDeclaredAccessorInfo()) {
11831202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    return GetDeclaredAccessorProperty(
11832202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org        receiver, Handle<DeclaredAccessorInfo>::cast(structure), isolate);
118337c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  }
118347c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
118359155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  UNREACHABLE();
11836202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  return MaybeHandle<Object>();
118379155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org}
118389155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
118399155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
118402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
118412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                                     Handle<Object> structure,
118422ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                                     uint32_t index,
118432ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                                     Handle<Object> value,
118442ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                                     Handle<JSObject> holder,
118452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                                     StrictMode strict_mode) {
11846528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Isolate* isolate = object->GetIsolate();
118479155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
118489155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // We should never get here to initialize a const with the hole
118499155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // value since a const declaration would conflict with the setter.
11850e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!value->IsTheHole());
11851e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!structure->IsForeign());
118527c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  if (structure->IsExecutableAccessorInfo()) {
118539155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    // api style callbacks
11854528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<ExecutableAccessorInfo> data =
11855528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        Handle<ExecutableAccessorInfo>::cast(structure);
118569155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    Object* call_obj = data->setter();
11857e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    v8::AccessorNameSetterCallback call_fun =
11858e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        v8::ToCData<v8::AccessorNameSetterCallback>(call_obj);
118599155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    if (call_fun == NULL) return value;
11860ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
11861ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Handle<String> key(isolate->factory()->NumberToString(number));
11862528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    LOG(isolate, ApiNamedPropertyAccess("store", *object, *key));
11863bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    PropertyCallbackArguments
11864528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        args(isolate, data->data(), *object, *holder);
118651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    args.Call(call_fun,
118661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org              v8::Utils::ToLocal(key),
11867528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org              v8::Utils::ToLocal(value));
118682ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
11869528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return value;
118709155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  }
118719155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
11872f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (structure->IsAccessorPair()) {
11873528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
11874c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (setter->IsSpecFunction()) {
11875c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // TODO(rossberg): nicer would be to cast to some JSCallable here...
11876528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      return SetPropertyWithDefinedSetter(
11877528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          object, Handle<JSReceiver>::cast(setter), value);
118789155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    } else {
11879486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      if (strict_mode == SLOPPY) return value;
11880ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      Handle<Object> key(isolate->factory()->NewNumberFromUint(index));
11881528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      Handle<Object> args[2] = { key, holder };
11882ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      THROW_NEW_ERROR(
11883ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org          isolate, NewTypeError("no_setter_in_callback", HandleVector(args, 2)),
11884ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org          Object);
118859155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org    }
118869155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  }
118879155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
118887c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  // TODO(dcarney): Handle correctly.
118897c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  if (structure->IsDeclaredAccessorInfo()) return value;
118907c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
118919155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  UNREACHABLE();
118922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return MaybeHandle<Object>();
118939155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org}
118949155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
118959155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
118967b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgbool JSObject::HasFastArgumentsElements() {
118977b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  Heap* heap = GetHeap();
118987b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (!elements()->IsFixedArray()) return false;
118997b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  FixedArray* elements = FixedArray::cast(this->elements());
11900486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (elements->map() != heap->sloppy_arguments_elements_map()) {
119017b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    return false;
119027b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
119037b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  FixedArray* arguments = FixedArray::cast(elements->get(1));
119047b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  return !arguments->IsDictionary();
119057b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org}
119067b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
119077b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
119087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgbool JSObject::HasDictionaryArgumentsElements() {
119097b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  Heap* heap = GetHeap();
119107b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (!elements()->IsFixedArray()) return false;
119117b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  FixedArray* elements = FixedArray::cast(this->elements());
11912486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (elements->map() != heap->sloppy_arguments_elements_map()) {
119137b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    return false;
119147b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
119157b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  FixedArray* arguments = FixedArray::cast(elements->get(1));
119167b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  return arguments->IsDictionary();
119177b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org}
119187b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
119197b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
1192043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Adding n elements in fast case is O(n*n).
1192143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Note: revisit design to have dual undefined values to capture absent
1192243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// elements.
119239e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSObject::SetFastElement(Handle<JSObject> object,
119249e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                             uint32_t index,
119259e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                             Handle<Object> value,
119269e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                             StrictMode strict_mode,
119279e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                             bool check_prototype) {
11928e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->HasFastSmiOrObjectElements() ||
11929b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org         object->HasFastArgumentsElements());
11930b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
11931b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
1193243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11933906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  // Array optimizations rely on the prototype lookups of Array objects always
11934906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  // returning undefined. If there is a store to the initial prototype object,
11935906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  // make sure all of these optimizations are invalidated.
11936b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (isolate->is_initial_object_prototype(*object) ||
11937b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      isolate->is_initial_array_prototype(*object)) {
11938b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate,
11939906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org        DependentCode::kElementsCantBeAddedGroup);
11940906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  }
11941906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
11942b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Handle<FixedArray> backing_store(FixedArray::cast(object->elements()));
11943b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (backing_store->map() ==
11944486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      isolate->heap()->sloppy_arguments_elements_map()) {
11945b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    backing_store = handle(FixedArray::cast(backing_store->get(1)));
119467b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  } else {
11947b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    backing_store = EnsureWritableFastElements(object);
11948303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  }
11949a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  uint32_t capacity = static_cast<uint32_t>(backing_store->length());
1195043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
119515d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  if (check_prototype &&
11952a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      (index >= capacity || backing_store->get(index)->IsTheHole())) {
11953d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com    bool found;
119549e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes(
11955b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        object, index, value, &found, strict_mode);
11956d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com    if (found) return result;
11957bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  }
11958bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
11959a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  uint32_t new_capacity = capacity;
11960a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  // Check if the length property of this object needs to be updated.
11961a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  uint32_t array_length = 0;
11962a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  bool must_update_array_length = false;
11963830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  bool introduces_holes = true;
11964b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (object->IsJSArray()) {
11965b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length));
11966830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    introduces_holes = index > array_length;
11967a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    if (index >= array_length) {
11968a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      must_update_array_length = true;
11969a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      array_length = index + 1;
11970c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
11971830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  } else {
11972830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    introduces_holes = index >= capacity;
11973a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  }
11974830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org
11975830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  // If the array is growing, and it's not growth by a single element at the
11976830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  // end, make sure that the ElementsKind is HOLEY.
11977b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  ElementsKind elements_kind = object->GetElementsKind();
11978830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (introduces_holes &&
11979830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      IsFastElementsKind(elements_kind) &&
11980830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      !IsFastHoleyElementsKind(elements_kind)) {
11981830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind);
11982b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    TransitionElementsKind(object, transitioned_kind);
11983830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  }
11984830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org
11985a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  // Check if the capacity of the backing store needs to be increased, or if
11986a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  // a transition to slow elements is necessary.
11987a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  if (index >= capacity) {
11988a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    bool convert_to_slow = true;
11989a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    if ((index - capacity) < kMaxGap) {
11990a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      new_capacity = NewElementsCapacity(index + 1);
11991e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(new_capacity > index);
11992b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      if (!object->ShouldConvertToSlowElements(new_capacity)) {
11993a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org        convert_to_slow = false;
1199443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1199543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
11996a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    if (convert_to_slow) {
11997b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      NormalizeElements(object);
11998b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      return SetDictionaryElement(object, index, value, NONE, strict_mode,
11999ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org                                  check_prototype);
12000a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    }
12001a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  }
12002a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  // Convert to fast double elements if appropriate.
12003b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (object->HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) {
1200459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // Consider fixing the boilerplate as well if we have one.
1200559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    ElementsKind to_kind = IsHoleyElementsKind(elements_kind)
1200659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        ? FAST_HOLEY_DOUBLE_ELEMENTS
1200759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        : FAST_DOUBLE_ELEMENTS;
1200859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
12009b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    UpdateAllocationSite(object, to_kind);
1201059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
12011b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    SetFastDoubleElementsCapacityAndLength(object, new_capacity, array_length);
12012b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    FixedDoubleArray::cast(object->elements())->set(index, value->Number());
1201349ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    JSObject::ValidateElements(object);
12014bdf2f942b9c2713af9965409f9dafa2f9f09b9ddager@chromium.org    return value;
1201543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
12016830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  // Change elements kind from Smi-only to generic FAST if necessary.
12017b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (object->HasFastSmiElements() && !value->IsSmi()) {
12018b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    ElementsKind kind = object->HasFastHoleyElements()
12019830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        ? FAST_HOLEY_ELEMENTS
12020830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        : FAST_ELEMENTS;
1202146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
12022b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    UpdateAllocationSite(object, kind);
12023b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<Map> new_map = GetElementsTransitionMap(object, kind);
1202497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    JSObject::MigrateToMap(object, new_map);
12025e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsFastObjectElementsKind(object->GetElementsKind()));
1202643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
12027a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  // Increase backing store capacity if that's been decided previously.
12028a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  if (new_capacity != capacity) {
12029830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    SetFastElementsCapacitySmiMode smi_mode =
12030b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        value->IsSmi() && object->HasFastSmiElements()
12031830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org            ? kAllowSmiElements
12032830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org            : kDontAllowSmiElements;
12033b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<FixedArray> new_elements =
12034b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        SetFastElementsCapacityAndLength(object, new_capacity, array_length,
12035b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                         smi_mode);
12036b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    new_elements->set(index, *value);
1203749ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    JSObject::ValidateElements(object);
12038a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    return value;
12039a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  }
12040830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org
12041a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  // Finally, set the new element and length.
12042e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->elements()->IsFixedArray());
12043b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  backing_store->set(index, *value);
12044a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  if (must_update_array_length) {
12045b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length));
12046a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  }
12047a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  return value;
120487b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org}
120497b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
120507b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
120519e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSObject::SetDictionaryElement(
120529e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Handle<JSObject> object,
120539e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    uint32_t index,
120549e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Handle<Object> value,
120559e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    PropertyAttributes attributes,
120569e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    StrictMode strict_mode,
120579e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    bool check_prototype,
120589e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    SetPropertyMode set_mode) {
12059e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->HasDictionaryElements() ||
12060b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org         object->HasDictionaryArgumentsElements());
12061b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
120627b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
120637b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Insert element in the dictionary.
12064b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Handle<FixedArray> elements(FixedArray::cast(object->elements()));
120657b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  bool is_arguments =
12066486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      (elements->map() == isolate->heap()->sloppy_arguments_elements_map());
120675323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org  Handle<SeededNumberDictionary> dictionary(is_arguments
120685323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    ? SeededNumberDictionary::cast(elements->get(1))
120695323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    : SeededNumberDictionary::cast(*elements));
120707b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
120717b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  int entry = dictionary->FindEntry(index);
12072f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  if (entry != SeededNumberDictionary::kNotFound) {
12073528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<Object> element(dictionary->ValueAt(entry), isolate);
120747b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    PropertyDetails details = dictionary->DetailsAt(entry);
12075ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) {
12076b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      return SetElementWithCallback(object, element, index, value, object,
12077b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                    strict_mode);
120787b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    } else {
120797b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      dictionary->UpdateMaxNumberKey(index);
12080f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      // If a value has not been initialized we allow writing to it even if it
12081ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      // is read-only (a declared const that has not been initialized).  If a
12082ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      // value is being defined we skip attribute checks completely.
12083ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      if (set_mode == DEFINE_PROPERTY) {
1208457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        details = PropertyDetails(
1208557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org            attributes, NORMAL, details.dictionary_index());
12086ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        dictionary->DetailsAtPut(entry, details);
12087ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      } else if (details.IsReadOnly() && !element->IsTheHole()) {
12088486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        if (strict_mode == SLOPPY) {
12089b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org          return isolate->factory()->undefined_value();
12090ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        } else {
12091ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org          Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12092b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org          Handle<Object> args[2] = { number, object };
12093ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org          THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property",
12094ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                                HandleVector(args, 2)),
12095ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                          Object);
12096ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        }
12097ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      }
12098ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      // Elements of the arguments object in slow mode might be slow aliases.
12099ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      if (is_arguments && element->IsAliasedArgumentsEntry()) {
12100b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        Handle<AliasedArgumentsEntry> entry =
12101b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org            Handle<AliasedArgumentsEntry>::cast(element);
12102b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        Handle<Context> context(Context::cast(elements->get(0)));
12103ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        int context_index = entry->aliased_context_slot();
12104e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(!context->get(context_index)->IsTheHole());
121055323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org        context->set(context_index, *value);
12106ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        // For elements that are still writable we keep slow aliasing.
12107528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        if (!details.IsReadOnly()) value = element;
121087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
121095323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org      dictionary->ValueAtPut(entry, *value);
121107b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
121117b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  } else {
121127b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // Index not already used. Look for an accessor in the prototype chain.
121135323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org    // Can cause GC!
121147b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (check_prototype) {
121157b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      bool found;
121169e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes(
121179e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org          object, index, value, &found, strict_mode);
121187b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      if (found) return result;
121197b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
12120b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
121217b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // When we set the is_extensible flag to false we always force the
121227b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // element into dictionary mode (and force them to stay there).
12123b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (!object->map()->is_extensible()) {
12124486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      if (strict_mode == SLOPPY) {
12125b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        return isolate->factory()->undefined_value();
121267b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      } else {
121277b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
121287b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        Handle<String> name = isolate->factory()->NumberToString(number);
121297b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        Handle<Object> args[1] = { name };
12130ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org        THROW_NEW_ERROR(isolate, NewTypeError("object_not_extensible",
12131ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                              HandleVector(args, 1)),
12132ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                        Object);
121337b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
121347b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
12135b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
1213657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
12137b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<SeededNumberDictionary> new_dictionary =
12138b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
12139b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                               details);
12140b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (*dictionary != *new_dictionary) {
121417b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      if (is_arguments) {
12142b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        elements->set(1, *new_dictionary);
121437b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      } else {
12144b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        object->set_elements(*new_dictionary);
121457b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
12146b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      dictionary = new_dictionary;
121477b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
121487b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
121497b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
121507b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Update the array length if this JSObject is an array.
12151b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (object->IsJSArray()) {
12152b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray>::cast(object), index,
12153b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                          value);
121547b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
121557b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
121567b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Attempt to put this object back in fast case.
12157b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (object->ShouldConvertToFastElements()) {
121587b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    uint32_t new_length = 0;
12159b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (object->IsJSArray()) {
12160b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&new_length));
121617b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    } else {
121627b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      new_length = dictionary->max_number_key() + 1;
121637b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
121643c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org    bool has_smi_only_elements = false;
121653c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org    bool should_convert_to_fast_double_elements =
12166b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        object->ShouldConvertToFastDoubleElements(&has_smi_only_elements);
12167474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    SetFastElementsCapacitySmiMode smi_mode =
12168474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        has_smi_only_elements ? kForceSmiElements : kAllowSmiElements;
12169b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
12170b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (should_convert_to_fast_double_elements) {
12171b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      SetFastDoubleElementsCapacityAndLength(object, new_length, new_length);
12172b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    } else {
12173b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      SetFastElementsCapacityAndLength(object, new_length, new_length,
12174b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                       smi_mode);
12175b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    }
1217649ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    JSObject::ValidateElements(object);
121777b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org#ifdef DEBUG
121787b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (FLAG_trace_normalization) {
12179f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      OFStream os(stdout);
12180f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << "Object elements are fast case again:\n";
12181f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      object->Print(os);
121827b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
121837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org#endif
121847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
12185b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  return value;
1218643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1218743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
121889e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSObject::SetFastDoubleElement(
12189b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<JSObject> object,
121906d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    uint32_t index,
12191b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<Object> value,
12192486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    StrictMode strict_mode,
121936d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    bool check_prototype) {
12194e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->HasFastDoubleElements());
121956d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
12196b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements()));
1219756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  uint32_t elms_length = static_cast<uint32_t>(base_elms->length());
121986d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
121996d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // If storing to an element that isn't in the array, pass the store request
122006d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // up the prototype chain before storing in the receiver's elements.
122016d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  if (check_prototype &&
1220256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org      (index >= elms_length ||
12203b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org       Handle<FixedDoubleArray>::cast(base_elms)->is_the_hole(index))) {
122046d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    bool found;
122059e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes(
122069e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org        object, index, value, &found, strict_mode);
122076d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    if (found) return result;
122086d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
122096d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
122106d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // If the value object is not a heap number, switch to fast elements and try
122116d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // again.
122126d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  bool value_is_smi = value->IsSmi();
12213830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  bool introduces_holes = true;
12214830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  uint32_t length = elms_length;
12215b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (object->IsJSArray()) {
12216b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&length));
12217830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    introduces_holes = index > length;
12218830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  } else {
12219830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    introduces_holes = index >= elms_length;
12220830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  }
12221830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org
122226d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  if (!value->IsNumber()) {
12223b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    SetFastElementsCapacityAndLength(object, elms_length, length,
12224b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                     kDontAllowSmiElements);
122259e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Handle<Object> result;
122269e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION(
122279e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org        object->GetIsolate(), result,
122289e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org        SetFastElement(object, index, value, strict_mode, check_prototype),
122299e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org        Object);
1223049ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    JSObject::ValidateElements(object);
12231b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    return result;
122326d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
122336d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
122346d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  double double_value = value_is_smi
12235b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      ? static_cast<double>(Handle<Smi>::cast(value)->value())
12236b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      : Handle<HeapNumber>::cast(value)->value();
122376d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
12238830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  // If the array is growing, and it's not growth by a single element at the
12239830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  // end, make sure that the ElementsKind is HOLEY.
12240b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  ElementsKind elements_kind = object->GetElementsKind();
12241830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (introduces_holes && !IsFastHoleyElementsKind(elements_kind)) {
12242830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind);
12243b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    TransitionElementsKind(object, transitioned_kind);
12244830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  }
12245830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org
122466d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // Check whether there is extra space in the fixed array.
122476d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  if (index < elms_length) {
12248b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<FixedDoubleArray> elms(FixedDoubleArray::cast(object->elements()));
122496d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    elms->set(index, double_value);
12250b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (object->IsJSArray()) {
122516d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      // Update the length of the array if needed.
122526d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      uint32_t array_length = 0;
12253b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      CHECK(
12254b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org          Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length));
122556d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      if (index >= array_length) {
12256b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        Handle<JSArray>::cast(object)->set_length(Smi::FromInt(index + 1));
122576d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      }
122586d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    }
122596d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    return value;
122606d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
122616d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
122626d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // Allow gap in fast case.
122636d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  if ((index - elms_length) < kMaxGap) {
122646d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    // Try allocating extra space.
122656d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    int new_capacity = NewElementsCapacity(index+1);
12266b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (!object->ShouldConvertToSlowElements(new_capacity)) {
12267e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(static_cast<uint32_t>(new_capacity) > index);
12268b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      SetFastDoubleElementsCapacityAndLength(object, new_capacity, index + 1);
12269b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      FixedDoubleArray::cast(object->elements())->set(index, double_value);
1227049ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org      JSObject::ValidateElements(object);
122716d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      return value;
122726d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    }
122736d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
122746d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
122756d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // Otherwise default to slow case.
12276e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->HasFastDoubleElements());
12277e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->map()->has_fast_double_elements());
12278e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->elements()->IsFixedDoubleArray() ||
12279f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org         object->elements()->length() == 0);
12280b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
12281b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  NormalizeElements(object);
12282e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->HasDictionaryElements());
12283b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  return SetElement(object, index, value, NONE, strict_mode, check_prototype);
122846d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org}
122856d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
122866d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
122879e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object,
122889e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                           uint32_t index,
122899e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                           Handle<Object> value,
122909e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                           PropertyAttributes attributes,
122919e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                           StrictMode strict_mode) {
122928fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  if (object->IsJSProxy()) {
122938fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    return JSProxy::SetElementWithHandler(
122948fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org        Handle<JSProxy>::cast(object), object, index, value, strict_mode);
12295ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  }
122968fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  return JSObject::SetElement(
122978fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org      Handle<JSObject>::cast(object), index, value, attributes, strict_mode);
12298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
12299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
12300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
123019e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSObject::SetOwnElement(Handle<JSObject> object,
123029e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                            uint32_t index,
123039e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                            Handle<Object> value,
123049e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                            StrictMode strict_mode) {
12305e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->HasExternalArrayElements());
12306b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  return JSObject::SetElement(object, index, value, NONE, strict_mode, false);
12307f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
12308f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
12309f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
123109e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object,
123119e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                         uint32_t index,
123129e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                         Handle<Object> value,
123139e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                         PropertyAttributes attributes,
123149e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                         StrictMode strict_mode,
123159e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                         bool check_prototype,
123169e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                         SetPropertyMode set_mode) {
12317b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
12318b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
12319a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org  if (object->HasExternalArrayElements() ||
12320a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org      object->HasFixedTypedArrayElements()) {
12321b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    if (!value->IsNumber() && !value->IsUndefined()) {
123222ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      ASSIGN_RETURN_ON_EXCEPTION(
123232ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          isolate, value,
123242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          Execution::ToNumber(isolate, value), Object);
12325f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    }
12326f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  }
12327e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1232843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check access rights if needed.
12329b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (object->IsAccessCheckNeeded()) {
12330c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_SET)) {
12331c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
123329e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
12333b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      return value;
12334c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
1233543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1233643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12337b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (object->IsJSGlobalProxy()) {
1233893720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    PrototypeIterator iter(isolate, object);
1233993720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    if (iter.IsAtEnd()) return value;
12340e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
1234193720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    return SetElement(
1234293720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index,
1234393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        value, attributes, strict_mode, check_prototype, set_mode);
12344ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  }
12345ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org
12346ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  // Don't allow element properties to be redefined for external arrays.
12347895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  if ((object->HasExternalArrayElements() ||
12348895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org          object->HasFixedTypedArrayElements()) &&
12349895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      set_mode == DEFINE_PROPERTY) {
12350ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12351b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<Object> args[] = { object, number };
12352ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    THROW_NEW_ERROR(isolate, NewTypeError("redef_external_array_element",
12353ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                          HandleVector(args, arraysize(args))),
12354ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                    Object);
12355ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  }
12356ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org
12357ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  // Normalize the elements to enable attributes on the property.
12358ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) {
12359b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
12360ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    // Make sure that we never go back to fast case.
12361ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    dictionary->set_requires_slow_elements();
123625a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
123635a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
1236497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  if (!object->map()->is_observed()) {
12365b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    return object->HasIndexedInterceptor()
123669e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      ? SetElementWithInterceptor(object, index, value, attributes,
123679e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                  strict_mode, check_prototype, set_mode)
12368b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      : SetElementWithoutInterceptor(object, index, value, attributes,
123699e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                     strict_mode, check_prototype, set_mode);
12370fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
12371fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
12372eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  Maybe<PropertyAttributes> maybe =
12373fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      JSReceiver::GetOwnElementAttribute(object, index);
12374eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  if (!maybe.has_value) return MaybeHandle<Object>();
12375eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  PropertyAttributes old_attributes = maybe.value;
12376eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org
12377fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  Handle<Object> old_value = isolate->factory()->the_hole_value();
12378d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<Object> old_length_handle;
12379d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<Object> new_length_handle;
12380fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
12381fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (old_attributes != ABSENT) {
12382fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    if (GetOwnElementAccessorPair(object, index).is_null()) {
123832ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      old_value = Object::GetElement(isolate, object, index).ToHandleChecked();
123844452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org    }
12385b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  } else if (object->IsJSArray()) {
12386fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // Store old array length in case adding an element grows the array.
12387b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    old_length_handle = handle(Handle<JSArray>::cast(object)->length(),
12388b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                               isolate);
12389e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
12390e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1239143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check for lookup interceptor
123929e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<Object> result;
123939e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
123949e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      isolate, result,
123959e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      object->HasIndexedInterceptor()
123969e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org          ? SetElementWithInterceptor(
123979e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org              object, index, value, attributes,
123989e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org              strict_mode, check_prototype, set_mode)
123999e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org          : SetElementWithoutInterceptor(
124009e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org              object, index, value, attributes,
124019e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org              strict_mode, check_prototype, set_mode),
124029e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      Object);
12403e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
12404fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  Handle<String> name = isolate->factory()->Uint32ToString(index);
12405eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  maybe = GetOwnElementAttribute(object, index);
12406eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  if (!maybe.has_value) return MaybeHandle<Object>();
12407eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  PropertyAttributes new_attributes = maybe.value;
12408eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org
12409fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (old_attributes == ABSENT) {
12410b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (object->IsJSArray() &&
12411b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        !old_length_handle->SameValue(
12412b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org            Handle<JSArray>::cast(object)->length())) {
12413b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      new_length_handle = handle(Handle<JSArray>::cast(object)->length(),
12414d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                                 isolate);
12415d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      uint32_t old_length = 0;
12416d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      uint32_t new_length = 0;
12417d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      CHECK(old_length_handle->ToArrayIndex(&old_length));
12418d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      CHECK(new_length_handle->ToArrayIndex(&new_length));
12419d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
12420b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      BeginPerformSplice(Handle<JSArray>::cast(object));
12421b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      EnqueueChangeRecord(object, "add", name, old_value);
12422b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      EnqueueChangeRecord(object, "update", isolate->factory()->length_string(),
12423d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                          old_length_handle);
12424b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      EndPerformSplice(Handle<JSArray>::cast(object));
12425d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
12426b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted,
12427d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                          new_length - old_length);
12428d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    } else {
12429b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      EnqueueChangeRecord(object, "add", name, old_value);
12430e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
12431e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  } else if (old_value->IsTheHole()) {
12432b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    EnqueueChangeRecord(object, "reconfigure", name, old_value);
12433e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  } else {
124347010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    Handle<Object> new_value =
124352ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        Object::GetElement(isolate, object, index).ToHandleChecked();
12436ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    bool value_changed = !old_value->SameValue(*new_value);
12437e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org    if (old_attributes != new_attributes) {
12438e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org      if (!value_changed) old_value = isolate->factory()->the_hole_value();
12439b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      EnqueueChangeRecord(object, "reconfigure", name, old_value);
12440e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org    } else if (value_changed) {
12441b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      EnqueueChangeRecord(object, "update", name, old_value);
12442e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org    }
1244343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1244443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12445b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  return result;
12446eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org}
12447eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
12448eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
124499e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgMaybeHandle<Object> JSObject::SetElementWithoutInterceptor(
12450b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<JSObject> object,
12451b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    uint32_t index,
12452b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<Object> value,
12453b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    PropertyAttributes attributes,
12454486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    StrictMode strict_mode,
12455b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    bool check_prototype,
12456b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    SetPropertyMode set_mode) {
12457e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->HasDictionaryElements() ||
12458b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org         object->HasDictionaryArgumentsElements() ||
12459b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org         (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0);
12460b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
124617c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  if (FLAG_trace_external_array_abuse &&
12462b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      IsExternalArrayElementsKind(object->GetElementsKind())) {
124639e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    CheckArrayAbuse(object, "external elements write", index);
124647c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  }
124657c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  if (FLAG_trace_js_array_abuse &&
12466b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      !IsExternalArrayElementsKind(object->GetElementsKind())) {
12467b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (object->IsJSArray()) {
124689e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      CheckArrayAbuse(object, "elements write", index, true);
124697c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    }
124707c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  }
12471fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  if (object->IsJSArray() && JSArray::WouldChangeReadOnlyLength(
12472fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      Handle<JSArray>::cast(object), index)) {
12473fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    if (strict_mode == SLOPPY) {
12474fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      return value;
12475fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    } else {
12476fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      return JSArray::ReadOnlyLengthError(Handle<JSArray>::cast(object));
12477fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    }
12478fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  }
12479b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  switch (object->GetElementsKind()) {
12480830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_SMI_ELEMENTS:
124810b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    case FAST_ELEMENTS:
12482830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_SMI_ELEMENTS:
12483830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_ELEMENTS:
12484b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      return SetFastElement(object, index, value, strict_mode, check_prototype);
124856d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    case FAST_DOUBLE_ELEMENTS:
12486830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_DOUBLE_ELEMENTS:
12487b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      return SetFastDoubleElement(object, index, value, strict_mode,
12488b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                  check_prototype);
12489af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
12490af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                       \
12491af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_##TYPE##_ELEMENTS: {                                        \
12492af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      Handle<External##Type##Array> array(                                    \
12493af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org          External##Type##Array::cast(object->elements()));                   \
12494af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      return External##Type##Array::SetValue(array, index, value);            \
12495af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    }                                                                         \
12496af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case TYPE##_ELEMENTS: {                                                   \
12497af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      Handle<Fixed##Type##Array> array(                                       \
12498af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org          Fixed##Type##Array::cast(object->elements()));                      \
12499af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      return Fixed##Type##Array::SetValue(array, index, value);               \
125005c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    }
12501af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
12502af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(TYPED_ARRAY_CASE)
12503af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
12504af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef TYPED_ARRAY_CASE
12505af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
125067b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    case DICTIONARY_ELEMENTS:
12507b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      return SetDictionaryElement(object, index, value, attributes, strict_mode,
12508b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                  check_prototype,
12509b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                  set_mode);
12510486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    case SLOPPY_ARGUMENTS_ELEMENTS: {
12511b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
125127b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      uint32_t length = parameter_map->length();
12513b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      Handle<Object> probe = index < length - 2 ?
12514b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org          Handle<Object>(parameter_map->get(index + 2), isolate) :
12515b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org          Handle<Object>();
12516b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      if (!probe.is_null() && !probe->IsTheHole()) {
12517b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        Handle<Context> context(Context::cast(parameter_map->get(0)));
12518b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        int context_index = Handle<Smi>::cast(probe)->value();
12519e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(!context->get(context_index)->IsTheHole());
12520b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        context->set(context_index, *value);
12521ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        // Redefining attributes of an aliased element destroys fast aliasing.
12522b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        if (set_mode == SET_PROPERTY || attributes == NONE) return value;
12523ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        parameter_map->set_the_hole(index + 2);
12524ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        // For elements that are still writable we re-establish slow aliasing.
12525b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        if ((attributes & READ_ONLY) == 0) {
12526b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org          value = Handle<Object>::cast(
12527b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org              isolate->factory()->NewAliasedArgumentsEntry(context_index));
125286d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        }
125290b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      }
12530b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
12531ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      if (arguments->IsDictionary()) {
12532b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        return SetDictionaryElement(object, index, value, attributes,
12533b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                    strict_mode,
12534b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                    check_prototype,
12535b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                    set_mode);
12536ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      } else {
12537b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        return SetFastElement(object, index, value, strict_mode,
12538b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                              check_prototype);
12539ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      }
125400b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    }
125410b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  }
125420b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // All possible cases have been handled above. Add a return to avoid the
125430b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // complaints from the compiler.
125440b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  UNREACHABLE();
12545b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  return isolate->factory()->null_value();
1254643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1254743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1254843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
125499801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.orgconst double AllocationSite::kPretenureRatio = 0.85;
12550c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org
12551c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org
12552034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.orgvoid AllocationSite::ResetPretenureDecision() {
125534ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  set_pretenure_decision(kUndecided);
125544ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  set_memento_found_count(0);
125554ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  set_memento_create_count(0);
12556034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org}
12557034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
12558034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
12559034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.orgPretenureFlag AllocationSite::GetPretenureMode() {
125604ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  PretenureDecision mode = pretenure_decision();
12561034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  // Zombie objects "decide" to be untenured.
1256209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  return mode == kTenure ? TENURED : NOT_TENURED;
12563034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org}
12564034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
12565034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
12566b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgbool AllocationSite::IsNestedSite() {
12567e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(FLAG_trace_track_allocation_sites);
12568b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  Object* current = GetHeap()->allocation_sites_list();
125694610c28af9f4355485f8115a725f320b80632804machenbach@chromium.org  while (current->IsAllocationSite()) {
12570b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    AllocationSite* current_site = AllocationSite::cast(current);
12571b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    if (current_site->nested_site() == this) {
12572b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      return true;
12573b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    }
12574b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    current = current_site->weak_next();
12575b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  }
12576b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  return false;
12577b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org}
12578b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
12579b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
125809b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.orgvoid AllocationSite::DigestTransitionFeedback(Handle<AllocationSite> site,
125819b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org                                              ElementsKind to_kind) {
125829b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  Isolate* isolate = site->GetIsolate();
1258346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
125849b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  if (site->SitePointsToLiteral() && site->transition_info()->IsJSArray()) {
125859b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    Handle<JSArray> transition_info =
125869b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org        handle(JSArray::cast(site->transition_info()));
12587bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    ElementsKind kind = transition_info->GetElementsKind();
12588169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    // if kind is holey ensure that to_kind is as well.
12589169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    if (IsHoleyElementsKind(kind)) {
12590169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      to_kind = GetHoleyElementsKind(to_kind);
12591169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    }
12592528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
125934a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      // If the array is huge, it's not likely to be defined in a local
125944a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      // function, so we shouldn't make new instances of it very often.
125954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      uint32_t length = 0;
12596bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      CHECK(transition_info->length()->ToArrayIndex(&length));
12597b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      if (length <= kMaximumArrayBytesToPretransition) {
125984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        if (FLAG_trace_track_allocation_sites) {
125999b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org          bool is_nested = site->IsNestedSite();
126004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org          PrintF(
12601b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org              "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n",
126029b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org              reinterpret_cast<void*>(*site),
12603b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org              is_nested ? "(nested)" : "",
126044a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org              ElementsKindToString(kind),
126054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org              ElementsKindToString(to_kind));
126064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org        }
126079b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org        JSObject::TransitionElementsKind(transition_info, to_kind);
126089b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org        site->dependent_code()->DeoptimizeDependentCodeGroup(
12609b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org            isolate, DependentCode::kAllocationSiteTransitionChangedGroup);
126104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      }
126114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    }
12612bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  } else {
126139b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    ElementsKind kind = site->GetElementsKind();
12614169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    // if kind is holey ensure that to_kind is as well.
12615169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    if (IsHoleyElementsKind(kind)) {
12616169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      to_kind = GetHoleyElementsKind(to_kind);
12617169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    }
12618528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
12619bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      if (FLAG_trace_track_allocation_sites) {
12620bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org        PrintF("AllocationSite: JSArray %p site updated %s->%s\n",
126219b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org               reinterpret_cast<void*>(*site),
12622bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org               ElementsKindToString(kind),
12623bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org               ElementsKindToString(to_kind));
1262459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      }
126259b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org      site->SetElementsKind(to_kind);
126269b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org      site->dependent_code()->DeoptimizeDependentCodeGroup(
12627b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org          isolate, DependentCode::kAllocationSiteTransitionChangedGroup);
1262859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    }
1262959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
1263059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org}
1263159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
1263259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
126334ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org// static
126344ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.orgvoid AllocationSite::AddDependentCompilationInfo(Handle<AllocationSite> site,
126354ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org                                                 Reason reason,
12636b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                                 CompilationInfo* info) {
126374ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  DependentCode::DependencyGroup group = site->ToDependencyGroup(reason);
126384ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  Handle<DependentCode> dep(site->dependent_code());
12639b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Handle<DependentCode> codes =
12640b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      DependentCode::Insert(dep, group, info->object_wrapper());
126414ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  if (*codes != site->dependent_code()) site->set_dependent_code(*codes);
126424ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  info->dependencies(group)->Add(Handle<HeapObject>(*site), info->zone());
12643b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org}
12644b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
12645b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
12646196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgconst char* AllocationSite::PretenureDecisionName(PretenureDecision decision) {
12647196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  switch (decision) {
12648196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    case kUndecided: return "undecided";
12649196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    case kDontTenure: return "don't tenure";
12650196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    case kMaybeTenure: return "maybe tenure";
12651196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    case kTenure: return "tenure";
12652196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    case kZombie: return "zombie";
12653196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    default: UNREACHABLE();
12654196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  }
12655196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  return NULL;
12656196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
12657196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
12658196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
12659b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgvoid JSObject::UpdateAllocationSite(Handle<JSObject> object,
12660b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                    ElementsKind to_kind) {
126619b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  if (!object->IsJSArray()) return;
12662b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
126639b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  Heap* heap = object->GetHeap();
126649b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  if (!heap->InNewSpace(*object)) return;
126659b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org
126669b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  Handle<AllocationSite> site;
126679b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  {
126689b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    DisallowHeapAllocation no_allocation;
126694ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org
126702ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    AllocationMemento* memento = heap->FindAllocationMemento(*object);
126712ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (memento == NULL) return;
12672b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
126739b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    // Walk through to the Allocation Site
126749b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    site = handle(memento->GetAllocationSite());
126759b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  }
126769b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  AllocationSite::DigestTransitionFeedback(site, to_kind);
12677b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org}
12678b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
12679b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
126809b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.orgvoid JSObject::TransitionElementsKind(Handle<JSObject> object,
126819b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org                                      ElementsKind to_kind) {
126829b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  ElementsKind from_kind = object->map()->elements_kind();
12683fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
12684830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (IsFastHoleyElementsKind(from_kind)) {
12685830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    to_kind = GetHoleyElementsKind(to_kind);
12686830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  }
12687830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org
126889b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  if (from_kind == to_kind) return;
12689e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  // Don't update the site if to_kind isn't fast
12690e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  if (IsFastElementsKind(to_kind)) {
126919b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    UpdateAllocationSite(object, to_kind);
12692e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  }
1269359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
126949b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
126959b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  if (object->elements() == isolate->heap()->empty_fixed_array() ||
12696830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      (IsFastSmiOrObjectElementsKind(from_kind) &&
12697830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org       IsFastSmiOrObjectElementsKind(to_kind)) ||
12698830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      (from_kind == FAST_DOUBLE_ELEMENTS &&
12699830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org       to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) {
12700e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(from_kind != TERMINAL_FAST_ELEMENTS_KIND);
12701830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    // No change is needed to the elements() buffer, the transition
12702830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    // only requires a map change.
127039b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    Handle<Map> new_map = GetElementsTransitionMap(object, to_kind);
127049b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    MigrateToMap(object, new_map);
12705fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    if (FLAG_trace_elements_transitions) {
127069b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org      Handle<FixedArrayBase> elms(object->elements());
127079b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org      PrintElementsTransition(stdout, object, from_kind, elms, to_kind, elms);
12708fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    }
127099b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    return;
12710fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  }
12711fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
127129b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  Handle<FixedArrayBase> elms(object->elements());
12713394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  uint32_t capacity = static_cast<uint32_t>(elms->length());
12714394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  uint32_t length = capacity;
1271564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
127169b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  if (object->IsJSArray()) {
127179b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    Object* raw_length = Handle<JSArray>::cast(object)->length();
1271864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    if (raw_length->IsUndefined()) {
1271964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      // If length is undefined, then JSArray is being initialized and has no
1272064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      // elements, assume a length of zero.
1272164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      length = 0;
1272264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    } else {
127239b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org      CHECK(raw_length->ToArrayIndex(&length));
1272464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    }
12725394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
1272664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
12727830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (IsFastSmiElementsKind(from_kind) &&
12728830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      IsFastDoubleElementsKind(to_kind)) {
127299b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    SetFastDoubleElementsCapacityAndLength(object, capacity, length);
1273049ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    JSObject::ValidateElements(object);
127319b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    return;
1273264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
1273364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
12734830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (IsFastDoubleElementsKind(from_kind) &&
12735830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      IsFastObjectElementsKind(to_kind)) {
127369b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    SetFastElementsCapacityAndLength(object, capacity, length,
127379b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org                                     kDontAllowSmiElements);
1273849ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    JSObject::ValidateElements(object);
127399b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org    return;
12740394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
1274164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
12742394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // This method should never be called for any other case than the ones
12743394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // handled above.
12744394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  UNREACHABLE();
12745394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
12746394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
12747394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
12748394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// static
12749394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.combool Map::IsValidElementsTransition(ElementsKind from_kind,
12750394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                    ElementsKind to_kind) {
12751830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  // Transitions can't go backwards.
12752830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
12753830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    return false;
12754830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  }
12755830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org
12756830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  // Transitions from HOLEY -> PACKED are not allowed.
12757830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  return !IsFastHoleyElementsKind(from_kind) ||
12758830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      IsFastHoleyElementsKind(to_kind);
12759394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
12760394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
12761394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
12762b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgvoid JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray> array,
12763b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                           uint32_t index,
12764b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                           Handle<Object> value) {
1276543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uint32_t old_len = 0;
12766e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  CHECK(array->length()->ToArrayIndex(&old_len));
1276743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check to see if we need to update the length. For now, we make
1276843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // sure that the length stays within 32-bits (unsigned).
1276943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (index >= old_len && index != 0xffffffff) {
12770e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<Object> len = array->GetIsolate()->factory()->NewNumber(
12771e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        static_cast<double>(index) + 1);
12772e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    array->set_length(*len);
1277343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1277443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1277543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1277643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12777fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgbool JSArray::IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map) {
127786474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Isolate* isolate = jsarray_map->GetIsolate();
127796474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  DCHECK(!jsarray_map->is_dictionary_map());
127806474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  LookupResult lookup(isolate);
127816474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Name> length_string = isolate->factory()->length_string();
127826474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  jsarray_map->LookupDescriptor(NULL, *length_string, &lookup);
127836474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  return lookup.IsReadOnly();
12784fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org}
12785fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org
12786fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org
12787fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgbool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
12788fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                                        uint32_t index) {
12789fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  uint32_t length = 0;
12790fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  CHECK(array->length()->ToArrayIndex(&length));
12791fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  if (length <= index) {
12792f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    LookupIterator it(array, array->GetIsolate()->factory()->length_string(),
127939aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org                      LookupIterator::OWN_SKIP_INTERCEPTOR);
127949aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org    CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
12795f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    CHECK(it.IsFound());
127961af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org    CHECK_EQ(LookupIterator::ACCESSOR, it.state());
12797f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org    return it.IsReadOnly();
12798fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  }
12799fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  return false;
12800fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org}
12801fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org
12802fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org
12803fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgMaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) {
12804fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  Isolate* isolate = array->GetIsolate();
12805fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  Handle<Name> length = isolate->factory()->length_string();
12806fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  Handle<Object> args[2] = { length, array };
12807ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property",
12808ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                        HandleVector(args, arraysize(args))),
12809ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                  Object);
12810fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org}
12811fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org
12812fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org
12813202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.orgMaybeHandle<Object> JSObject::GetElementWithInterceptor(
12814202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    Handle<JSObject> object,
12815202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    Handle<Object> receiver,
12816202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    uint32_t index) {
12817b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  Isolate* isolate = object->GetIsolate();
12818dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
1281943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make sure that the top context does not change when doing
1282043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // callbacks or interceptor calls.
12821fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  AssertNoContextChange ncc(isolate);
12822dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
12823b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor(), isolate);
1282443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!interceptor->getter()->IsUndefined()) {
12825662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    v8::IndexedPropertyGetterCallback getter =
12826662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org        v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
12827ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    LOG(isolate,
12828b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org        ApiIndexedPropertyAccess("interceptor-indexed-get", *object, index));
12829bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    PropertyCallbackArguments
12830b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org        args(isolate, interceptor->data(), *receiver, *object);
128311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    v8::Handle<v8::Value> result = args.Call(getter, index);
128328496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
12833de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    if (!result.IsEmpty()) {
12834de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
12835de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      result_internal->VerifyApiCallResultType();
12836b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org      // Rebox handle before return.
12837202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      return handle(*result_internal, isolate);
12838de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    }
1283943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1284043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12841b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  ElementsAccessor* handler = object->GetElementsAccessor();
12842202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  Handle<Object> result;
12843202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
12844202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      isolate, result, handler->Get(receiver,  object, index),
12845202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      Object);
12846b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  if (!result->IsTheHole()) return result;
128473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1284893720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  PrototypeIterator iter(isolate, object);
1284993720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  if (iter.IsAtEnd()) return isolate->factory()->undefined_value();
1285093720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  return Object::GetElementWithReceiver(
1285193720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org      isolate, PrototypeIterator::GetCurrent(iter), receiver, index);
1285243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1285343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1285443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1285543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool JSObject::HasDenseElements() {
1285643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int capacity = 0;
128572c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  int used = 0;
128582c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  GetElementsCapacityAndUsage(&capacity, &used);
128592c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  return (capacity == 0) || (used > (capacity / 2));
128602c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org}
128612c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org
128622c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org
128632c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.orgvoid JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) {
128642c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  *capacity = 0;
128652c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  *used = 0;
1286643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1286784bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements());
1286884bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org  FixedArray* backing_store = NULL;
128690b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  switch (GetElementsKind()) {
12870486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    case SLOPPY_ARGUMENTS_ELEMENTS:
1287184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      backing_store_base =
1287284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org          FixedArray::cast(FixedArray::cast(backing_store_base)->get(1));
1287384bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      backing_store = FixedArray::cast(backing_store_base);
128747b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      if (backing_store->IsDictionary()) {
12875f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        SeededNumberDictionary* dictionary =
12876f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com            SeededNumberDictionary::cast(backing_store);
128772c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org        *capacity = dictionary->Capacity();
128782c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org        *used = dictionary->NumberOfElements();
128797b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        break;
128807b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
128817b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      // Fall through.
12882830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_SMI_ELEMENTS:
128837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    case FAST_ELEMENTS:
128847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      if (IsJSArray()) {
128857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        *capacity = backing_store_base->length();
128867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        *used = Smi::cast(JSArray::cast(this)->length())->value();
128877028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        break;
128887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      }
128897028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      // Fall through if packing is not guaranteed.
12890830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_SMI_ELEMENTS:
12891830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_ELEMENTS:
1289284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org      backing_store = FixedArray::cast(backing_store_base);
128932c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      *capacity = backing_store->length();
128942c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      for (int i = 0; i < *capacity; ++i) {
128952c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org        if (!backing_store->get(i)->IsTheHole()) ++(*used);
128960b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      }
128970b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
128987b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    case DICTIONARY_ELEMENTS: {
12899b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      SeededNumberDictionary* dictionary = element_dictionary();
129002c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      *capacity = dictionary->Capacity();
129012c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      *used = dictionary->NumberOfElements();
129027b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      break;
1290343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
12904830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_DOUBLE_ELEMENTS:
129057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      if (IsJSArray()) {
129067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        *capacity = backing_store_base->length();
129077028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        *used = Smi::cast(JSArray::cast(this)->length())->value();
129087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        break;
129097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      }
129107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      // Fall through if packing is not guaranteed.
12911830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_DOUBLE_ELEMENTS: {
12912f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      *capacity = elements()->length();
12913f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      if (*capacity == 0) break;
12914f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      FixedDoubleArray * elms = FixedDoubleArray::cast(elements());
129152c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      for (int i = 0; i < *capacity; i++) {
129162c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org        if (!elms->is_the_hole(i)) ++(*used);
129176d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      }
129186d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      break;
129196d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    }
12920af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
12921af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
12922af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_##TYPE##_ELEMENTS:                                         \
12923af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case TYPE##_ELEMENTS:                                                    \
12924af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
12925af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(TYPED_ARRAY_CASE)
12926af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef TYPED_ARRAY_CASE
12927af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    {
129282c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      // External arrays are considered 100% used.
129295c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      FixedArrayBase* external_array = FixedArrayBase::cast(elements());
129302c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      *capacity = external_array->length();
129312c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      *used = external_array->length();
129322c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      break;
129335c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    }
1293443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1293543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1293643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1293743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1293850bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.orgbool JSObject::WouldConvertToSlowElements(Handle<Object> key) {
1293950bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org  uint32_t index;
1294050bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org  if (HasFastElements() && key->ToArrayIndex(&index)) {
1294150bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org    Handle<FixedArrayBase> backing_store(FixedArrayBase::cast(elements()));
1294250bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org    uint32_t capacity = static_cast<uint32_t>(backing_store->length());
1294350bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org    if (index >= capacity) {
1294450bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org      if ((index - capacity) >= kMaxGap) return true;
1294550bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org      uint32_t new_capacity = NewElementsCapacity(index + 1);
1294650bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org      return ShouldConvertToSlowElements(new_capacity);
1294750bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org    }
1294850bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org  }
1294950bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org  return false;
1295050bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org}
1295150bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org
1295250bb868e274f7f873f683d591048376427ffdd72jkummerow@chromium.org
129539a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.combool JSObject::ShouldConvertToSlowElements(int new_capacity) {
129542c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  STATIC_ASSERT(kMaxUncheckedOldFastElementsLength <=
129552c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org                kMaxUncheckedFastElementsLength);
129562c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  if (new_capacity <= kMaxUncheckedOldFastElementsLength ||
129572c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      (new_capacity <= kMaxUncheckedFastElementsLength &&
129582c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org       GetHeap()->InNewSpace(this))) {
129592c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    return false;
129606d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
129612c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  // If the fast-case backing storage takes up roughly three times as
129622c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  // much space (in machine words) as a dictionary backing storage
129632c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  // would, the object should have slow elements.
129642c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  int old_capacity = 0;
129652c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  int used_elements = 0;
129662c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  GetElementsCapacityAndUsage(&old_capacity, &used_elements);
12967f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  int dictionary_size = SeededNumberDictionary::ComputeCapacity(used_elements) *
12968f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      SeededNumberDictionary::kEntrySize;
129692c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  return 3 * dictionary_size <= new_capacity;
1297043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1297143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1297243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
129739a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.combool JSObject::ShouldConvertToFastElements() {
12974e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(HasDictionaryElements() || HasDictionaryArgumentsElements());
1297543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the elements are sparse, we should not go back to fast case.
1297643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!HasDenseElements()) return false;
1297743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // An object requiring access checks is never allowed to have fast
1297843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // elements.  If it had fast elements we would skip security checks.
1297943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (IsAccessCheckNeeded()) return false;
12980a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Observed objects may not go to fast mode because they rely on map checks,
12981a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // and for fast element accesses we sometimes check element kinds only.
1298297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  if (map()->is_observed()) return false;
129837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
129847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  FixedArray* elements = FixedArray::cast(this->elements());
12985f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  SeededNumberDictionary* dictionary = NULL;
12986486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (elements->map() == GetHeap()->sloppy_arguments_elements_map()) {
12987f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    dictionary = SeededNumberDictionary::cast(elements->get(1));
129887b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  } else {
12989f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    dictionary = SeededNumberDictionary::cast(elements);
129907b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
129917b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // If an element has been added at a very high index in the elements
129927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // dictionary, we cannot go back to fast case.
129937b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  if (dictionary->requires_slow_elements()) return false;
1299443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the dictionary backing storage takes up roughly half as much
129952c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  // space (in machine words) as a fast-case backing storage would,
129962c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  // the object should have fast elements.
129972c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  uint32_t array_size = 0;
1299843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (IsJSArray()) {
129992c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_size));
1300043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
130012c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    array_size = dictionary->max_number_key();
1300243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
130032c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) *
13004f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      SeededNumberDictionary::kEntrySize;
130052c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  return 2 * dictionary_size >= array_size;
1300643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1300743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1300843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
130093c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.orgbool JSObject::ShouldConvertToFastDoubleElements(
130103c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org    bool* has_smi_only_elements) {
130113c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org  *has_smi_only_elements = false;
130129b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  if (HasSloppyArgumentsElements()) return false;
130136d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  if (FLAG_unbox_double_arrays) {
13014e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(HasDictionaryElements());
13015b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    SeededNumberDictionary* dictionary = element_dictionary();
130163c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org    bool found_double = false;
130176d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    for (int i = 0; i < dictionary->Capacity(); i++) {
130186d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      Object* key = dictionary->KeyAt(i);
130196d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      if (key->IsNumber()) {
130203c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org        Object* value = dictionary->ValueAt(i);
130213c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org        if (!value->IsNumber()) return false;
130223c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org        if (!value->IsSmi()) {
130233c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org          found_double = true;
130243c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org        }
130256d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      }
130266d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    }
130273c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org    *has_smi_only_elements = !found_double;
130283c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org    return found_double;
130296d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  } else {
130306d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    return false;
130316d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
130326d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org}
130336d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
130346d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
1303586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org// Certain compilers request function template instantiation when they
1303686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org// see the definition of the other template functions in the
1303786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org// class. This requires us to have the template functions put
1303886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org// together, so even though this function belongs in objects-debug.cc,
1303986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org// we keep it here instead to satisfy certain compilers.
13040023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org#ifdef OBJECT_PRINT
13041f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgtemplate <typename Derived, typename Shape, typename Key>
13042f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgvoid Dictionary<Derived, Shape, Key>::Print(OStream& os) {  // NOLINT
13043c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  int capacity = DerivedHashTable::Capacity();
1304486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  for (int i = 0; i < capacity; i++) {
13045c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    Object* k = DerivedHashTable::KeyAt(i);
13046c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    if (DerivedHashTable::IsKey(k)) {
13047f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << " ";
1304886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      if (k->IsString()) {
13049f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        String::cast(k)->StringPrint(os);
1305086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      } else {
13051f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << Brief(k);
1305286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      }
13053f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      os << ": " << Brief(ValueAt(i)) << "\n";
1305486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org    }
1305586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  }
1305686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org}
1305786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org#endif
1305886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
1305986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
13060c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
13061c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgvoid Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) {
1306243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int pos = 0;
13063c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  int capacity = DerivedHashTable::Capacity();
1306479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
13065b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
1306643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < capacity; i++) {
13067c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    Object* k =  Dictionary::KeyAt(i);
13068c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    if (Dictionary::IsKey(k)) {
1306986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      elements->set(pos++, ValueAt(i), mode);
1307086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org    }
1307143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
13072e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(pos == elements->length());
1307343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1307443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1307543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1307643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenInterceptorInfo* JSObject::GetNamedInterceptor() {
13077e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(map()->has_named_interceptor());
1307843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  JSFunction* constructor = JSFunction::cast(map()->constructor());
13079e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(constructor->shared()->IsApiFunction());
1308043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* result =
13081f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org      constructor->shared()->get_api_func_data()->named_property_handler();
1308243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return InterceptorInfo::cast(result);
1308343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1308443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1308543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1308643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenInterceptorInfo* JSObject::GetIndexedInterceptor() {
13087e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(map()->has_indexed_interceptor());
1308843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  JSFunction* constructor = JSFunction::cast(map()->constructor());
13089e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(constructor->shared()->IsApiFunction());
1309043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* result =
13091f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org      constructor->shared()->get_api_func_data()->indexed_property_handler();
1309243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return InterceptorInfo::cast(result);
1309343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1309443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1309543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
130968f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgMaybeHandle<Object> JSObject::GetPropertyWithInterceptor(
130978ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org    Handle<JSObject> holder,
13098dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org    Handle<Object> receiver,
130998ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org    Handle<Name> name) {
131008ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  Isolate* isolate = holder->GetIsolate();
13101dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org
13102750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // TODO(rossberg): Support symbols in the API.
13103dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  if (name->IsSymbol()) return isolate->factory()->undefined_value();
13104750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
131058ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor(), isolate);
13106dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  Handle<String> name_string = Handle<String>::cast(name);
1310743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
131088ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  if (interceptor->getter()->IsUndefined()) return MaybeHandle<Object>();
131098ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org
131108ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  v8::NamedPropertyGetterCallback getter =
131118ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org      v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
131128ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  LOG(isolate,
131138ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org      ApiNamedPropertyAccess("interceptor-named-get", *holder, *name));
131148ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  PropertyCallbackArguments
131158ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org      args(isolate, interceptor->data(), *receiver, *holder);
131168ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  v8::Handle<v8::Value> result =
131178ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org      args.Call(getter, v8::Utils::ToLocal(name_string));
131188ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
131198ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  if (result.IsEmpty()) return MaybeHandle<Object>();
13120e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
131218ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
131228ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  result_internal->VerifyApiCallResultType();
131238ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  // Rebox handle before return
131248ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  return handle(*result_internal, isolate);
1312543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1312643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1312743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
131289fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org// Compute the property keys from the interceptor.
131299fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org// TODO(rossberg): support symbols in API, and filter here if needed.
131303484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgMaybeHandle<JSObject> JSObject::GetKeysForNamedInterceptor(
131319fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<JSObject> object, Handle<JSReceiver> receiver) {
131329fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Isolate* isolate = receiver->GetIsolate();
131339fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
131349fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  PropertyCallbackArguments
131359fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      args(isolate, interceptor->data(), *receiver, *object);
131363484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  v8::Handle<v8::Object> result;
131379fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (!interceptor->enumerator()->IsUndefined()) {
131389fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    v8::NamedPropertyEnumeratorCallback enum_fun =
131399fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        v8::ToCData<v8::NamedPropertyEnumeratorCallback>(
131409fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org            interceptor->enumerator());
131419fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    LOG(isolate, ApiObjectAccess("interceptor-named-enum", *object));
131429fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    result = args.Call(enum_fun);
131439fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
131443484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  if (result.IsEmpty()) return MaybeHandle<JSObject>();
131459fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org#if ENABLE_EXTRA_CHECKS
131463484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  CHECK(v8::Utils::OpenHandle(*result)->IsJSArray() ||
131473484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org        v8::Utils::OpenHandle(*result)->HasSloppyArgumentsElements());
131489fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org#endif
131499fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Rebox before returning.
131509fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return handle(*v8::Utils::OpenHandle(*result), isolate);
131519fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
131529fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
131539fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
131549fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org// Compute the element keys from the interceptor.
131553484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgMaybeHandle<JSObject> JSObject::GetKeysForIndexedInterceptor(
131569fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<JSObject> object, Handle<JSReceiver> receiver) {
131579fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Isolate* isolate = receiver->GetIsolate();
131589fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
131599fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  PropertyCallbackArguments
131609fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      args(isolate, interceptor->data(), *receiver, *object);
131613484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  v8::Handle<v8::Object> result;
131629fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (!interceptor->enumerator()->IsUndefined()) {
131639fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    v8::IndexedPropertyEnumeratorCallback enum_fun =
131649fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        v8::ToCData<v8::IndexedPropertyEnumeratorCallback>(
131659fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org            interceptor->enumerator());
131669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    LOG(isolate, ApiObjectAccess("interceptor-indexed-enum", *object));
131679fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    result = args.Call(enum_fun);
131689fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  }
131693484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  if (result.IsEmpty()) return MaybeHandle<JSObject>();
131709fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org#if ENABLE_EXTRA_CHECKS
131713484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  CHECK(v8::Utils::OpenHandle(*result)->IsJSArray() ||
131723484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org        v8::Utils::OpenHandle(*result)->HasSloppyArgumentsElements());
131739fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org#endif
131749fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Rebox before returning.
131759fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return handle(*v8::Utils::OpenHandle(*result), isolate);
131769fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
131779fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
131789fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
13179eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgMaybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object,
13180eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                           Handle<Name> key) {
131816474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
13182f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org  Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
13183f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org  if (!maybe_result.has_value) return Maybe<bool>();
13184f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org  return maybe(it.IsFound());
1318543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1318643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1318743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13188eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgMaybe<bool> JSObject::HasRealElementProperty(Handle<JSObject> object,
13189eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                             uint32_t index) {
131900fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org  Isolate* isolate = object->GetIsolate();
13191381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  HandleScope scope(isolate);
1319243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check access rights if needed.
131930fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org  if (object->IsAccessCheckNeeded()) {
13194c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) {
13195c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
13196eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<bool>());
13197eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      return maybe(false);
13198c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
1319943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1320043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
132010fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org  if (object->IsJSGlobalProxy()) {
132020fdb2a65d0f07bb7f6d6ce2f8337e00e5c9c323dbmeurer@chromium.org    HandleScope scope(isolate);
1320393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    PrototypeIterator iter(isolate, object);
13204eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    if (iter.IsAtEnd()) return maybe(false);
13205e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
1320693720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    return HasRealElementProperty(
1320793720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index);
13208169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
13209169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
13210eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  Maybe<PropertyAttributes> result =
13211eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org      GetElementAttributeWithoutInterceptor(object, object, index, false);
13212eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  if (!result.has_value) return Maybe<bool>();
13213eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  return maybe(result.value != ABSENT);
1321443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1321543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1321643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13217eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgMaybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
13218eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org                                                   Handle<Name> key) {
132196474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
13220f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org  Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
13221f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org  if (!maybe_result.has_value) return Maybe<bool>();
132221af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org  return maybe(it.state() == LookupIterator::ACCESSOR);
1322343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1322443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1322543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13226fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgint JSObject::NumberOfOwnProperties(PropertyAttributes filter) {
1322733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  if (HasFastProperties()) {
1322833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    Map* map = this->map();
1322933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    if (filter == NONE) return map->NumberOfOwnDescriptors();
13230750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (filter & DONT_ENUM) {
1323133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      int result = map->EnumLength();
13232af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org      if (result != kInvalidEnumCacheSentinel) return result;
1323333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    }
1323433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter);
1323533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  }
1323633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  return property_dictionary()->NumberOfElementsFilterAttributes(filter);
1323743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1323843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1323943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1324065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgvoid FixedArray::SwapPairs(FixedArray* numbers, int i, int j) {
1324143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* temp = get(i);
1324243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  set(i, get(j));
1324343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  set(j, temp);
1324465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  if (this != numbers) {
1324565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    temp = numbers->get(i);
132460ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    numbers->set(i, Smi::cast(numbers->get(j)));
132470ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    numbers->set(j, Smi::cast(temp));
1324865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  }
1324943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1325043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1325143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1325265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgstatic void InsertionSortPairs(FixedArray* content,
1325365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org                               FixedArray* numbers,
1325465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org                               int len) {
1325543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 1; i < len; i++) {
1325643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int j = i;
1325743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    while (j > 0 &&
1325865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org           (NumberToUint32(numbers->get(j - 1)) >
1325965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org            NumberToUint32(numbers->get(j)))) {
1326065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      content->SwapPairs(numbers, j - 1, j);
1326143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      j--;
1326243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1326343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1326443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1326543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1326643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1326765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgvoid HeapSortPairs(FixedArray* content, FixedArray* numbers, int len) {
1326843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // In-place heap sort.
13269e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(content->length() == numbers->length());
1327043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1327143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Bottom-up max-heap construction.
1327243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 1; i < len; ++i) {
1327343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int child_index = i;
1327443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    while (child_index > 0) {
1327543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      int parent_index = ((child_index + 1) >> 1) - 1;
1327665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      uint32_t parent_value = NumberToUint32(numbers->get(parent_index));
1327765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      uint32_t child_value = NumberToUint32(numbers->get(child_index));
1327843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (parent_value < child_value) {
1327965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org        content->SwapPairs(numbers, parent_index, child_index);
1328043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
1328143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break;
1328243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1328343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      child_index = parent_index;
1328443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1328543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1328643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1328743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Extract elements and create sorted array.
1328843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = len - 1; i > 0; --i) {
1328943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Put max element at the back of the array.
1329065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    content->SwapPairs(numbers, 0, i);
1329143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Sift down the new top element.
1329243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int parent_index = 0;
1329343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    while (true) {
1329443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      int child_index = ((parent_index + 1) << 1) - 1;
1329543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (child_index >= i) break;
1329665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      uint32_t child1_value = NumberToUint32(numbers->get(child_index));
1329765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      uint32_t child2_value = NumberToUint32(numbers->get(child_index + 1));
1329865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      uint32_t parent_value = NumberToUint32(numbers->get(parent_index));
1329943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (child_index + 1 >= i || child1_value > child2_value) {
1330043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (parent_value > child1_value) break;
1330165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org        content->SwapPairs(numbers, parent_index, child_index);
1330243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        parent_index = child_index;
1330343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
1330443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        if (parent_value > child2_value) break;
1330565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org        content->SwapPairs(numbers, parent_index, child_index + 1);
1330643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        parent_index = child_index + 1;
1330743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1330843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1330943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1331043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1331143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1331243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1331365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org// Sort this array and the numbers as pairs wrt. the (distinct) numbers.
1331465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgvoid FixedArray::SortPairs(FixedArray* numbers, uint32_t len) {
13315e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(this->length() == numbers->length());
1331643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // For small arrays, simply use insertion sort.
1331743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (len <= 10) {
1331865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    InsertionSortPairs(this, numbers, len);
1331943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
1332043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1332143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check the range of indices.
1332265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  uint32_t min_index = NumberToUint32(numbers->get(0));
1332365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  uint32_t max_index = min_index;
1332465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  uint32_t i;
1332543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (i = 1; i < len; i++) {
1332665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    if (NumberToUint32(numbers->get(i)) < min_index) {
1332765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      min_index = NumberToUint32(numbers->get(i));
1332865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    } else if (NumberToUint32(numbers->get(i)) > max_index) {
1332965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      max_index = NumberToUint32(numbers->get(i));
1333043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1333143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1333243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (max_index - min_index + 1 == len) {
1333343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Indices form a contiguous range, unless there are duplicates.
1333465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    // Do an in-place linear time sort assuming distinct numbers, but
1333543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // avoid hanging in case they are not.
1333643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (i = 0; i < len; i++) {
1333765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      uint32_t p;
1333865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      uint32_t j = 0;
1333943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // While the current element at i is not at its correct position p,
1334043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // swap the elements at these two positions.
1334165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      while ((p = NumberToUint32(numbers->get(i)) - min_index) != i &&
1334243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen             j++ < len) {
1334365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org        SwapPairs(numbers, i, p);
1334443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1334543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1334643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
1334765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    HeapSortPairs(this, numbers, len);
1334843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
1334943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1335043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1335143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1335243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13353fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org// Fill in the names of own properties into the supplied storage. The main
1335443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// purpose of this function is to provide reflection information for the object
1335543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// mirrors.
133568a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.orgvoid JSObject::GetOwnPropertyNames(
133578a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org    FixedArray* storage, int index, PropertyAttributes filter) {
13358e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(storage->length() >= (NumberOfOwnProperties(filter) - index));
1335943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (HasFastProperties()) {
1336006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    int real_size = map()->NumberOfOwnDescriptors();
13361defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    DescriptorArray* descs = map()->instance_descriptors();
1336206ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    for (int i = 0; i < real_size; i++) {
13363f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      if ((descs->GetDetails(i).attributes() & filter) == 0 &&
13364034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org          !FilterKey(descs->GetKey(i), filter)) {
133658a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org        storage->set(index++, descs->GetKey(i));
13366f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      }
1336743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1336843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
133698a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org    property_dictionary()->CopyKeysTo(storage,
133708a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org                                      index,
133718a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org                                      filter,
133728a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org                                      NameDictionary::UNSORTED);
1337343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1337443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1337543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1337643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13377fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgint JSObject::NumberOfOwnElements(PropertyAttributes filter) {
13378fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  return GetOwnElementKeys(NULL, filter);
1337943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1338043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1338143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1338243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint JSObject::NumberOfEnumElements() {
13383ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  // Fast case for objects with no elements.
13384830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  if (!IsJSValue() && HasFastObjectElements()) {
13385ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org    uint32_t length = IsJSArray() ?
13386ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org        static_cast<uint32_t>(
13387ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org            Smi::cast(JSArray::cast(this)->length())->value()) :
13388ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org        static_cast<uint32_t>(FixedArray::cast(elements())->length());
13389ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org    if (length == 0) return 0;
13390ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  }
13391ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  // Compute the number of enumerable elements.
13392fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  return NumberOfOwnElements(static_cast<PropertyAttributes>(DONT_ENUM));
1339343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1339443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1339543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13396fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgint JSObject::GetOwnElementKeys(FixedArray* storage,
13397fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                                PropertyAttributes filter) {
1339843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int counter = 0;
133990b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  switch (GetElementsKind()) {
13400830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_SMI_ELEMENTS:
13401830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_ELEMENTS:
13402830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_SMI_ELEMENTS:
13403830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_ELEMENTS: {
134040b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      int length = IsJSArray() ?
134050b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org          Smi::cast(JSArray::cast(this)->length())->value() :
134060b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org          FixedArray::cast(elements())->length();
134070b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      for (int i = 0; i < length; i++) {
134080b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org        if (!FixedArray::cast(elements())->get(i)->IsTheHole()) {
134090b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org          if (storage != NULL) {
13410b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org            storage->set(counter, Smi::FromInt(i));
134110b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org          }
134120b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org          counter++;
134130b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org        }
134140b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      }
13415e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(!storage || storage->length() >= counter);
134160b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
134170b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    }
13418830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_DOUBLE_ELEMENTS:
13419830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    case FAST_HOLEY_DOUBLE_ELEMENTS: {
13420717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org      int length = IsJSArray() ?
13421717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org          Smi::cast(JSArray::cast(this)->length())->value() :
13422fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org          FixedArrayBase::cast(elements())->length();
13423717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org      for (int i = 0; i < length; i++) {
13424717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org        if (!FixedDoubleArray::cast(elements())->is_the_hole(i)) {
13425717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org          if (storage != NULL) {
13426717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org            storage->set(counter, Smi::FromInt(i));
13427717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org          }
13428717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org          counter++;
13429717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org        }
13430717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org      }
13431e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(!storage || storage->length() >= counter);
13432717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org      break;
13433717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org    }
13434af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
13435af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
13436af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_##TYPE##_ELEMENTS:                                         \
13437af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case TYPE##_ELEMENTS:                                                    \
13438af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
13439af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(TYPED_ARRAY_CASE)
13440af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef TYPED_ARRAY_CASE
13441af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    {
134425c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      int length = FixedArrayBase::cast(elements())->length();
134433811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      while (counter < length) {
134443811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org        if (storage != NULL) {
13445b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org          storage->set(counter, Smi::FromInt(counter));
134463811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org        }
134473811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org        counter++;
134483811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      }
13449e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(!storage || storage->length() >= counter);
134503811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      break;
134513811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
13452af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
134530b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    case DICTIONARY_ELEMENTS: {
134540b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      if (storage != NULL) {
134556db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org        element_dictionary()->CopyKeysTo(storage,
134566db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                         filter,
13457f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                                         SeededNumberDictionary::SORTED);
134580b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      }
134597b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      counter += element_dictionary()->NumberOfElementsFilterAttributes(filter);
134600b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
134619a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    }
13462486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    case SLOPPY_ARGUMENTS_ELEMENTS: {
134637b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      FixedArray* parameter_map = FixedArray::cast(elements());
134646db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org      int mapped_length = parameter_map->length() - 2;
134657b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
134667b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      if (arguments->IsDictionary()) {
134676db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org        // Copy the keys from arguments first, because Dictionary::CopyKeysTo
134686db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org        // will insert in storage starting at index 0.
13469f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        SeededNumberDictionary* dictionary =
13470f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com            SeededNumberDictionary::cast(arguments);
134716db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org        if (storage != NULL) {
13472f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com          dictionary->CopyKeysTo(
13473f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com              storage, filter, SeededNumberDictionary::UNSORTED);
134746db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org        }
134757b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        counter += dictionary->NumberOfElementsFilterAttributes(filter);
134766db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org        for (int i = 0; i < mapped_length; ++i) {
134776db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org          if (!parameter_map->get(i + 2)->IsTheHole()) {
134786db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org            if (storage != NULL) storage->set(counter, Smi::FromInt(i));
134796db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org            ++counter;
134806db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org          }
134816db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org        }
134826db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org        if (storage != NULL) storage->SortPairs(storage, counter);
134836db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
134847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      } else {
134856db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org        int backing_length = arguments->length();
134866db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org        int i = 0;
134876db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org        for (; i < mapped_length; ++i) {
134886db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org          if (!parameter_map->get(i + 2)->IsTheHole()) {
134896db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org            if (storage != NULL) storage->set(counter, Smi::FromInt(i));
134906db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org            ++counter;
134916db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org          } else if (i < backing_length && !arguments->get(i)->IsTheHole()) {
134926db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org            if (storage != NULL) storage->set(counter, Smi::FromInt(i));
134937b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org            ++counter;
134947b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          }
134957b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        }
134966db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org        for (; i < backing_length; ++i) {
134976db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org          if (storage != NULL) storage->set(counter, Smi::FromInt(i));
134986db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org          ++counter;
134996db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org        }
135007b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
135010b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      break;
135027b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
1350343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1350443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1350543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (this->IsJSValue()) {
1350643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Object* val = JSValue::cast(this)->value();
1350743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (val->IsString()) {
1350843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      String* str = String::cast(val);
1350943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (storage) {
13510bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org        for (int i = 0; i < str->length(); i++) {
13511b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org          storage->set(counter + i, Smi::FromInt(i));
1351243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
1351343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
13514bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      counter += str->length();
1351543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1351643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
13517e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!storage || storage->length() == counter);
1351843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return counter;
1351943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1352043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1352143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1352243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint JSObject::GetEnumElementKeys(FixedArray* storage) {
13523fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  return GetOwnElementKeys(storage, static_cast<PropertyAttributes>(DONT_ENUM));
1352443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1352543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1352643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13527381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org// StringSharedKeys are used as keys in the eval cache.
13528381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgclass StringSharedKey : public HashTableKey {
13529381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org public:
135309e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  StringSharedKey(Handle<String> source,
135319e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                  Handle<SharedFunctionInfo> shared,
13532486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                  StrictMode strict_mode,
1353304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org                  int scope_position)
1353483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org      : source_(source),
1353583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org        shared_(shared),
13536486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        strict_mode_(strict_mode),
1353704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org        scope_position_(scope_position) { }
13538381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
13539ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  bool IsMatch(Object* other) OVERRIDE {
135409e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    DisallowHeapAllocation no_allocation;
13541381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org    if (!other->IsFixedArray()) return false;
1354204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    FixedArray* other_array = FixedArray::cast(other);
1354304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
135449e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    if (shared != *shared_) return false;
13545486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    int strict_unchecked = Smi::cast(other_array->get(2))->value();
13546e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(strict_unchecked == SLOPPY || strict_unchecked == STRICT);
13547486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked);
13548486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    if (strict_mode != strict_mode_) return false;
1354904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    int scope_position = Smi::cast(other_array->get(3))->value();
1355004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    if (scope_position != scope_position_) return false;
1355104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    String* source = String::cast(other_array->get(1));
135529e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    return source->Equals(*source_);
13553381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  }
13554381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
13555381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  static uint32_t StringSharedHashHelper(String* source,
1355683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                                         SharedFunctionInfo* shared,
13557486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                                         StrictMode strict_mode,
1355804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org                                         int scope_position) {
13559381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org    uint32_t hash = source->Hash();
13560381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org    if (shared->HasSourceCode()) {
13561381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org      // Instead of using the SharedFunctionInfo pointer in the hash
13562381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org      // code computation, we use a combination of the hash of the
1356304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org      // script source code and the start position of the calling scope.
1356404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org      // We do this to ensure that the cache entries can survive garbage
13565381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org      // collection.
135669e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      Script* script(Script::cast(shared->script()));
13567381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org      hash ^= String::cast(script->source())->Hash();
13568486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      if (strict_mode == STRICT) hash ^= 0x8000;
1356904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org      hash += scope_position;
13570381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org    }
13571381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org    return hash;
13572381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  }
13573381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
13574ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  uint32_t Hash() OVERRIDE {
135759e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    return StringSharedHashHelper(*source_, *shared_, strict_mode_,
135769e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                  scope_position_);
1357786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  }
1357886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
13579ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  uint32_t HashForObject(Object* obj) OVERRIDE {
135809e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    DisallowHeapAllocation no_allocation;
1358104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    FixedArray* other_array = FixedArray::cast(obj);
1358204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
1358304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    String* source = String::cast(other_array->get(1));
13584486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    int strict_unchecked = Smi::cast(other_array->get(2))->value();
13585e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(strict_unchecked == SLOPPY || strict_unchecked == STRICT);
13586486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked);
1358704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    int scope_position = Smi::cast(other_array->get(3))->value();
135881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    return StringSharedHashHelper(
13589486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        source, shared, strict_mode, scope_position);
13590381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  }
13591381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
135929e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org
13593ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  Handle<Object> AsHandle(Isolate* isolate) OVERRIDE {
13594865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    Handle<FixedArray> array = isolate->factory()->NewFixedArray(4);
135959e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    array->set(0, *shared_);
135969e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    array->set(1, *source_);
135979e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    array->set(2, Smi::FromInt(strict_mode_));
135989e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    array->set(3, Smi::FromInt(scope_position_));
135999e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    return array;
13600381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  }
13601381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
13602381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org private:
136039e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<String> source_;
136049e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<SharedFunctionInfo> shared_;
13605486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  StrictMode strict_mode_;
1360604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  int scope_position_;
13607381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org};
13608381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
13609381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
136109fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org// RegExpKey carries the source and flags of a regular expression as key.
136119fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.orgclass RegExpKey : public HashTableKey {
136129fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org public:
136139e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  RegExpKey(Handle<String> string, JSRegExp::Flags flags)
13614a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      : string_(string),
13615a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        flags_(Smi::FromInt(flags.value())) { }
136169fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
136179d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // Rather than storing the key in the hash table, a pointer to the
136189d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // stored value is stored where the key should be.  IsMatch then
136199d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // compares the search key to the found object, rather than comparing
136209d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // a key to a key.
13621ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  bool IsMatch(Object* obj) OVERRIDE {
136229fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    FixedArray* val = FixedArray::cast(obj);
136239fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    return string_->Equals(String::cast(val->get(JSRegExp::kSourceIndex)))
136249fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org        && (flags_ == val->get(JSRegExp::kFlagsIndex));
136259fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  }
136269fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
13627ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  uint32_t Hash() OVERRIDE { return RegExpHash(*string_, flags_); }
136289fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
13629ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  Handle<Object> AsHandle(Isolate* isolate) OVERRIDE {
136309fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    // Plain hash maps, which is where regexp keys are used, don't
136319fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    // use this function.
136329fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    UNREACHABLE();
13633865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    return MaybeHandle<Object>().ToHandleChecked();
136349fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  }
136359fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
13636ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  uint32_t HashForObject(Object* obj) OVERRIDE {
136379fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    FixedArray* val = FixedArray::cast(obj);
136389fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    return RegExpHash(String::cast(val->get(JSRegExp::kSourceIndex)),
136399fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org                      Smi::cast(val->get(JSRegExp::kFlagsIndex)));
136409fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  }
136419fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
136429fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  static uint32_t RegExpHash(String* string, Smi* flags) {
136439fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org    return string->Hash() + flags->value();
136449fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  }
136459fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
136469e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<String> string_;
136479fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  Smi* flags_;
136489fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org};
136499fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
13650e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
13651865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.orgHandle<Object> OneByteStringKey::AsHandle(Isolate* isolate) {
1365243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  if (hash_field_ == 0) Hash();
13653865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  return isolate->factory()->NewOneByteInternalizedString(string_, hash_field_);
1365443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org}
1365540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
1365640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
13657865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.orgHandle<Object> TwoByteStringKey::AsHandle(Isolate* isolate) {
1365809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  if (hash_field_ == 0) Hash();
13659865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  return isolate->factory()->NewTwoByteInternalizedString(string_, hash_field_);
1366009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org}
1366109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
1366209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
136635e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgHandle<Object> SeqOneByteSubStringKey::AsHandle(Isolate* isolate) {
1366443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  if (hash_field_ == 0) Hash();
136655e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return isolate->factory()->NewOneByteInternalizedSubString(
136665e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      string_, from_, length_, hash_field_);
1366743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org}
136689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
136699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
136705e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgbool SeqOneByteSubStringKey::IsMatch(Object* string) {
136715e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
1367209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  return String::cast(string)->IsOneByteEqualTo(chars);
1367343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org}
136749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
136759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
136764a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org// InternalizedStringKey carries a string/internalized-string object as key.
136774a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgclass InternalizedStringKey : public HashTableKey {
1367843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
13679b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  explicit InternalizedStringKey(Handle<String> string)
13680ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      : string_(string) { }
1368143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13682ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool IsMatch(Object* string) OVERRIDE {
13683b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org    return String::cast(string)->Equals(*string_);
1368443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1368543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13686ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual uint32_t Hash() OVERRIDE { return string_->Hash(); }
1368743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13688ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual uint32_t HashForObject(Object* other) OVERRIDE {
1368986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org    return String::cast(other)->Hash();
1369086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  }
1369186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
13692ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Handle<Object> AsHandle(Isolate* isolate) OVERRIDE {
136934a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // Internalize the string if possible.
13694865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    MaybeHandle<Map> maybe_map =
13695865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org        isolate->factory()->InternalizedStringMapForString(string_);
13696865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    Handle<Map> map;
13697865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    if (maybe_map.ToHandle(&map)) {
13698865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      string_->set_map_no_write_barrier(*map);
13699e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(string_->IsInternalizedString());
13700865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      return string_;
1370143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
137024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // Otherwise allocate a new internalized string.
13703865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    return isolate->factory()->NewInternalizedStringImpl(
13704865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org        string_, string_->length(), string_->hash_field());
1370543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1370643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1370743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static uint32_t StringHash(Object* obj) {
1370843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return String::cast(obj)->Hash();
1370943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1371043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13711b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  Handle<String> string_;
1371243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
1371343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1371443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13715c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
13716c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgvoid HashTable<Derived, Shape, Key>::IteratePrefix(ObjectVisitor* v) {
1371743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  IteratePointers(v, 0, kElementsStartOffset);
1371843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1371943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1372043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13721c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
13722c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgvoid HashTable<Derived, Shape, Key>::IterateElements(ObjectVisitor* v) {
1372343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  IteratePointers(v,
1372443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                  kElementsStartOffset,
1372543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                  kHeaderSize + length() * kPointerSize);
1372643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1372743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1372843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13729c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
13730865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.orgHandle<Derived> HashTable<Derived, Shape, Key>::New(
13731865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    Isolate* isolate,
13732c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    int at_least_space_for,
13733c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    MinimumCapacity capacity_option,
13734c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    PretenureFlag pretenure) {
13735e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(0 <= at_least_space_for);
1373621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  DCHECK(!capacity_option || base::bits::IsPowerOfTwo32(at_least_space_for));
13737000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY)
13738000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org                     ? at_least_space_for
13739000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org                     : ComputeCapacity(at_least_space_for);
137402c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  if (capacity > HashTable::kMaxCapacity) {
13741a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
137420c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
137430c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
13744865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Factory* factory = isolate->factory();
13745865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  int length = EntryToIndex(capacity);
13746865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Handle<FixedArray> array = factory->NewFixedArray(length, pretenure);
13747865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  array->set_map_no_write_barrier(*factory->hash_table_map());
13748865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Handle<Derived> table = Handle<Derived>::cast(array);
1374943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13750865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  table->SetNumberOfElements(0);
13751865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  table->SetNumberOfDeletedElements(0);
13752865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  table->SetCapacity(capacity);
13753865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  return table;
13754c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org}
13755c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
13756c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
13757f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org// Find entry for key otherwise return kNotFound.
13758f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgint NameDictionary::FindEntry(Handle<Name> key) {
13759750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (!key->IsUniqueName()) {
13760c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    return DerivedHashTable::FindEntry(key);
137614980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org  }
137624980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org
13763750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Optimized for unique names. Knowledge of the key type allows:
13764750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // 1. Move the check if the key is unique out of the loop.
13765750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // 2. Avoid comparing hash codes in unique-to-unique comparison.
13766750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // 3. Detect a case when a dictionary key is not unique but the key is.
137674a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  //    In case of positive result the dictionary key may be replaced by the
137684a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  //    internalized string with minimal performance penalty. It gives a chance
137694a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  //    to perform further lookups in code stubs (and significant performance
137704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  //    boost a certain style of code).
137714980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org
137724980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org  // EnsureCapacity will guarantee the hash table is never full.
137734980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org  uint32_t capacity = Capacity();
137744980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org  uint32_t entry = FirstProbe(key->Hash(), capacity);
137754980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org  uint32_t count = 1;
137764980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org
137774980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org  while (true) {
137784980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org    int index = EntryToIndex(entry);
137794980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org    Object* element = get(index);
137804980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org    if (element->IsUndefined()) break;  // Empty entry.
13781f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    if (*key == element) return entry;
13782750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (!element->IsUniqueName() &&
13783c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        !element->IsTheHole() &&
13784f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org        Name::cast(element)->Equals(*key)) {
13785750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      // Replace a key that is a non-internalized string by the equivalent
137864a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      // internalized string for faster further lookups.
13787f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      set(index, *key);
137884980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org      return entry;
137894980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org    }
13790e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(element->IsTheHole() || !Name::cast(element)->Equals(*key));
137914980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org    entry = NextProbe(entry, count++, capacity);
137924980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org  }
137934980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org  return kNotFound;
137944980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org}
137954980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org
137964980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org
13797c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
13798865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.orgvoid HashTable<Derived, Shape, Key>::Rehash(
13799865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    Handle<Derived> new_table,
13800865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    Key key) {
13801e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(NumberOfElements() < new_table->Capacity());
1380204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
1380379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
1380404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc);
1380504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
1380604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  // Copy prefix to new array.
1380704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  for (int i = kPrefixStartIndex;
1380804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org       i < kPrefixStartIndex + Shape::kPrefixSize;
1380904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org       i++) {
1381004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    new_table->set(i, get(i), mode);
1381104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  }
1381204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
1381304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  // Rehash the elements.
1381404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  int capacity = Capacity();
1381504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  for (int i = 0; i < capacity; i++) {
1381604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    uint32_t from_index = EntryToIndex(i);
1381704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    Object* k = get(from_index);
1381804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    if (IsKey(k)) {
13819c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      uint32_t hash = HashTable::HashForObject(key, k);
1382004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      uint32_t insertion_index =
1382104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org          EntryToIndex(new_table->FindInsertionEntry(hash));
1382204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      for (int j = 0; j < Shape::kEntrySize; j++) {
1382304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org        new_table->set(insertion_index + j, get(from_index + j), mode);
1382404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      }
1382504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    }
1382604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  }
1382704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  new_table->SetNumberOfElements(NumberOfElements());
1382804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  new_table->SetNumberOfDeletedElements(0);
1382904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org}
1383004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
1383104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
13832c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
13833c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orguint32_t HashTable<Derived, Shape, Key>::EntryForProbe(
13834c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    Key key,
13835c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    Object* k,
13836c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    int probe,
13837c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    uint32_t expected) {
13838c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  uint32_t hash = HashTable::HashForObject(key, k);
138394a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  uint32_t capacity = Capacity();
138404a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  uint32_t entry = FirstProbe(hash, capacity);
138414a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  for (int i = 1; i < probe; i++) {
138424a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    if (entry == expected) return expected;
138434a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    entry = NextProbe(entry, i, capacity);
138444a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  }
138454a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  return entry;
138464a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org}
138474a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
138484a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
13849c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
13850c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgvoid HashTable<Derived, Shape, Key>::Swap(uint32_t entry1,
13851c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                                          uint32_t entry2,
13852c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                                          WriteBarrierMode mode) {
138534a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  int index1 = EntryToIndex(entry1);
138544a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  int index2 = EntryToIndex(entry2);
138554a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  Object* temp[Shape::kEntrySize];
138564a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  for (int j = 0; j < Shape::kEntrySize; j++) {
138574a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    temp[j] = get(index1 + j);
138584a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  }
138594a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  for (int j = 0; j < Shape::kEntrySize; j++) {
138604a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    set(index1 + j, get(index2 + j), mode);
138614a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  }
138624a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  for (int j = 0; j < Shape::kEntrySize; j++) {
138634a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    set(index2 + j, temp[j], mode);
138644a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  }
138654a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org}
138664a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
138674a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
13868c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
13869c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgvoid HashTable<Derived, Shape, Key>::Rehash(Key key) {
138704a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  DisallowHeapAllocation no_gc;
138714a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  WriteBarrierMode mode = GetWriteBarrierMode(no_gc);
138724a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  uint32_t capacity = Capacity();
138734a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  bool done = false;
138744a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  for (int probe = 1; !done; probe++) {
138754a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // All elements at entries given by one of the first _probe_ probes
138764a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    // are placed correctly. Other elements might need to be moved.
138774a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    done = true;
138784a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    for (uint32_t current = 0; current < capacity; current++) {
138794a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      Object* current_key = get(EntryToIndex(current));
138804a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      if (IsKey(current_key)) {
138814a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        uint32_t target = EntryForProbe(key, current_key, probe, current);
138824a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        if (current == target) continue;
138834a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        Object* target_key = get(EntryToIndex(target));
138844a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        if (!IsKey(target_key) ||
138854a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org            EntryForProbe(key, target_key, probe, target) != target) {
138864a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          // Put the current element into the correct position.
138874a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          Swap(current, target, mode);
138884a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          // The other element will be processed on the next iteration.
138894a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          current--;
138904a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        } else {
138914a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          // The place for the current element is occupied. Leave the element
138924a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          // for the next probe.
138934a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org          done = false;
138944a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        }
138954a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      }
138964a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    }
138974a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  }
138984a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org}
138994a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
139004a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
13901c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
13902865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.orgHandle<Derived> HashTable<Derived, Shape, Key>::EnsureCapacity(
13903865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    Handle<Derived> table,
13904c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    int n,
13905c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    Key key,
13906c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    PretenureFlag pretenure) {
13907865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Isolate* isolate = table->GetIsolate();
13908865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  int capacity = table->Capacity();
13909865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  int nof = table->NumberOfElements() + n;
13910865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  int nod = table->NumberOfDeletedElements();
13911edf0cd1f0a597ded80ff7c8ab0e5ffdbcb7a5391kasperl@chromium.org  // Return if:
13912edf0cd1f0a597ded80ff7c8ab0e5ffdbcb7a5391kasperl@chromium.org  //   50% is still free after adding n elements and
13913edf0cd1f0a597ded80ff7c8ab0e5ffdbcb7a5391kasperl@chromium.org  //   at most 50% of the free elements are deleted elements.
13914ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (nod <= (capacity - nof) >> 1) {
13915ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    int needed_free = nof >> 1;
13916865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    if (nof + needed_free <= capacity) return table;
13917ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
1391843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13919ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  const int kMinCapacityForPretenure = 256;
1392025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  bool should_pretenure = pretenure == TENURED ||
13921865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      ((capacity > kMinCapacityForPretenure) &&
13922865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org          !isolate->heap()->InNewSpace(*table));
13923865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Handle<Derived> new_table = HashTable::New(
13924f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      isolate,
13925865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      nof * 2,
13926865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      USE_DEFAULT_MINIMUM_CAPACITY,
13927865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      should_pretenure ? TENURED : NOT_TENURED);
13928865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org
13929865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  table->Rehash(new_table, key);
13930865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  return new_table;
139319fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
139329fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
139339fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
139349fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
13935c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgHandle<Derived> HashTable<Derived, Shape, Key>::Shrink(Handle<Derived> table,
13936c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                                                       Key key) {
13937c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  int capacity = table->Capacity();
13938c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  int nof = table->NumberOfElements();
1393904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
1394004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  // Shrink to fit the number of elements if only a quarter of the
1394104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  // capacity is filled with elements.
13942c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  if (nof > (capacity >> 2)) return table;
1394304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  // Allocate a new dictionary with room for at least the current
1394404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  // number of elements. The allocation method will make sure that
1394504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  // there is extra room in the dictionary for additions. Don't go
1394604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  // lower than room for 16 elements.
1394704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  int at_least_room_for = nof;
13948c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  if (at_least_room_for < 16) return table;
1394904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
13950c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  Isolate* isolate = table->GetIsolate();
1395104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  const int kMinCapacityForPretenure = 256;
1395204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  bool pretenure =
1395304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      (at_least_room_for > kMinCapacityForPretenure) &&
13954c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      !isolate->heap()->InNewSpace(*table);
13955865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Handle<Derived> new_table = HashTable::New(
13956c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      isolate,
13957c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      at_least_room_for,
13958c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      USE_DEFAULT_MINIMUM_CAPACITY,
13959c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org      pretenure ? TENURED : NOT_TENURED);
1396004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
13961865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  table->Rehash(new_table, key);
13962c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  return new_table;
1396343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1396443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1396543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13966c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
13967c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orguint32_t HashTable<Derived, Shape, Key>::FindInsertionEntry(uint32_t hash) {
1396843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  uint32_t capacity = Capacity();
139690c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  uint32_t entry = FirstProbe(hash, capacity);
139700c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  uint32_t count = 1;
139710c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // EnsureCapacity will guarantee the hash table is never full.
139720c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  while (true) {
139730c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    Object* element = KeyAt(entry);
13974c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (element->IsUndefined() || element->IsTheHole()) break;
139750c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    entry = NextProbe(entry, count++, capacity);
1397643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1397743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return entry;
1397843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1397943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13980e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1398186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org// Force instantiation of template instances class.
1398286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org// Please note this list is compiler dependent.
1398386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
13984c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate class HashTable<StringTable, StringTableShape, HashTableKey*>;
1398586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
13986c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate class HashTable<CompilationCacheTable,
13987c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                         CompilationCacheShape,
13988c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                         HashTableKey*>;
1398986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
13990c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate class HashTable<MapCache, MapCacheShape, HashTableKey*>;
1399186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
13992865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.orgtemplate class HashTable<ObjectHashTable,
13993865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org                         ObjectHashTableShape,
13994865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org                         Handle<Object> >;
139957943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
13996865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.orgtemplate class HashTable<WeakHashTable, WeakHashTableShape<2>, Handle<Object> >;
1399725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
13998f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgtemplate class Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >;
1399986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
14000c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate class Dictionary<SeededNumberDictionary,
14001c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                          SeededNumberDictionaryShape,
14002c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                          uint32_t>;
1400386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
14004c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate class Dictionary<UnseededNumberDictionary,
14005c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                          UnseededNumberDictionaryShape,
14006c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                          uint32_t>;
14007f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
14008865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.orgtemplate Handle<SeededNumberDictionary>
14009c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgDictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
14010865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    New(Isolate*, int at_least_space_for, PretenureFlag pretenure);
14011f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
14012865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.orgtemplate Handle<UnseededNumberDictionary>
14013c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgDictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
14014865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    New(Isolate*, int at_least_space_for, PretenureFlag pretenure);
1401586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
140169fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgtemplate Handle<NameDictionary>
14017f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgDictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
14018865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    New(Isolate*, int n, PretenureFlag pretenure);
140199fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
14020f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgtemplate Handle<SeededNumberDictionary>
14021c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgDictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
14022f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    AtPut(Handle<SeededNumberDictionary>, uint32_t, Handle<Object>);
1402386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
14024f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgtemplate Handle<UnseededNumberDictionary>
14025c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgDictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
14026f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    AtPut(Handle<UnseededNumberDictionary>, uint32_t, Handle<Object>);
14027f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
14028c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate Object*
14029c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgDictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
1403065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org    SlowReverseLookup(Object* value);
1403165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org
14032c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate Object*
14033f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgDictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
14034f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    SlowReverseLookup(Object* value);
1403586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
14036c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate void
14037c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgDictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
14038c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    CopyKeysTo(
14039c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        FixedArray*,
14040c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        PropertyAttributes,
14041c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org        Dictionary<SeededNumberDictionary,
14042c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                   SeededNumberDictionaryShape,
14043c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org                   uint32_t>::SortMode);
14044c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
14045c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate Handle<Object>
14046f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgDictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::DeleteProperty(
14047865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    Handle<NameDictionary>, int, JSObject::DeleteMode);
1404886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
140495b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.orgtemplate Handle<Object>
14050c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgDictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
14051865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    DeleteProperty(Handle<SeededNumberDictionary>, int, JSObject::DeleteMode);
14052c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
14053c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate Handle<NameDictionary>
14054f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHashTable<NameDictionary, NameDictionaryShape, Handle<Name> >::
140559fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    New(Isolate*, int, MinimumCapacity, PretenureFlag);
140569fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
140579fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgtemplate Handle<NameDictionary>
14058f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHashTable<NameDictionary, NameDictionaryShape, Handle<Name> >::
14059f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Shrink(Handle<NameDictionary>, Handle<Name>);
14060c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
14061c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate Handle<SeededNumberDictionary>
14062c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgHashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
14063c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    Shrink(Handle<SeededNumberDictionary>, uint32_t);
14064c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
140658a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.orgtemplate void Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
140668a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org    CopyKeysTo(
140678a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org        FixedArray*,
140688a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org        int,
140698a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org        PropertyAttributes,
140708a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org        Dictionary<
140718a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org            NameDictionary, NameDictionaryShape, Handle<Name> >::SortMode);
1407286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
1407386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.orgtemplate int
14074f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgDictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
14075c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    NumberOfElementsFilterAttributes(PropertyAttributes);
1407686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
14077f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgtemplate Handle<NameDictionary>
14078f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgDictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::Add(
14079f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails);
1408043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14081f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgtemplate void
14082f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgDictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
14083f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    GenerateNewEnumerationIndices(Handle<NameDictionary>);
1408443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1408586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.orgtemplate int
14086c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgDictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
14087f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    NumberOfElementsFilterAttributes(PropertyAttributes);
1408843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14089f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgtemplate Handle<SeededNumberDictionary>
14090f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgDictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
14091f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Add(Handle<SeededNumberDictionary>,
14092f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org        uint32_t,
14093f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org        Handle<Object>,
14094f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org        PropertyDetails);
1409543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14096f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgtemplate Handle<UnseededNumberDictionary>
14097c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgDictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
14098f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Add(Handle<UnseededNumberDictionary>,
14099f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org        uint32_t,
14100f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org        Handle<Object>,
14101f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org        PropertyDetails);
14102f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
14103f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgtemplate Handle<SeededNumberDictionary>
14104c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgDictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
14105f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    EnsureCapacity(Handle<SeededNumberDictionary>, int, uint32_t);
14106f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
14107f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgtemplate Handle<UnseededNumberDictionary>
14108c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgDictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
14109f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    EnsureCapacity(Handle<UnseededNumberDictionary>, int, uint32_t);
1411043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14111f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgtemplate Handle<NameDictionary>
14112f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgDictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
14113f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    EnsureCapacity(Handle<NameDictionary>, int, Handle<Name>);
141149258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
1411586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.orgtemplate
14116c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgint Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
14117c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    NumberOfEnumElements();
1411886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
1411986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.orgtemplate
14120f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgint Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
14121c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    NumberOfEnumElements();
141229258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
141230c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgtemplate
14124c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgint HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
14125c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    FindEntry(uint32_t);
14126c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
14127c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org
14128ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.orgHandle<Object> JSObject::PrepareSlowElementsForSort(
14129ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    Handle<JSObject> object, uint32_t limit) {
14130e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->HasDictionaryElements());
14131e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Isolate* isolate = object->GetIsolate();
141325ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  // Must stay in dictionary mode, either because of requires_slow_elements,
141335ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  // or because we are not going to sort (and therefore compact) all of the
141345ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  // elements.
14135e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate);
14136e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Handle<SeededNumberDictionary> new_dict =
14137865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      SeededNumberDictionary::New(isolate, dict->NumberOfElements());
141385ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
141395ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  uint32_t pos = 0;
141405ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  uint32_t undefs = 0;
14141ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int capacity = dict->Capacity();
14142e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  Handle<Smi> bailout(Smi::FromInt(-1), isolate);
14143e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  // Entry to the new dictionary does not cause it to grow, as we have
14144e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  // allocated one that is large enough for all entries.
14145e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  DisallowHeapAllocation no_gc;
141465ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  for (int i = 0; i < capacity; i++) {
141475ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    Object* k = dict->KeyAt(i);
14148e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    if (!dict->IsKey(k)) continue;
14149e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
14150e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(k->IsNumber());
14151e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0);
14152e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0);
14153e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32);
14154e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
14155e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    HandleScope scope(isolate);
14156e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<Object> value(dict->ValueAt(i), isolate);
14157e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    PropertyDetails details = dict->DetailsAt(i);
14158e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    if (details.type() == CALLBACKS || details.IsReadOnly()) {
14159e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      // Bail out and do the sorting of undefineds and array holes in JS.
14160e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      // Also bail out if the element is not supposed to be moved.
14161e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      return bailout;
14162e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    }
14163e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
14164e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    uint32_t key = NumberToUint32(k);
14165e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    if (key < limit) {
14166e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      if (value->IsUndefined()) {
14167e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        undefs++;
14168e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
14169e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        // Adding an entry with the key beyond smi-range requires
14170e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        // allocation. Bailout.
14171e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        return bailout;
141725ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      } else {
14173e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
14174e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org            new_dict, pos, value, details);
14175e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(result.is_identical_to(new_dict));
14176e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        USE(result);
14177e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        pos++;
141785ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      }
14179e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    } else if (key > static_cast<uint32_t>(Smi::kMaxValue)) {
14180e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      // Adding an entry with the key beyond smi-range requires
14181e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      // allocation. Bailout.
14182e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      return bailout;
14183e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    } else {
14184e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
14185e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org          new_dict, key, value, details);
14186e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(result.is_identical_to(new_dict));
14187e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      USE(result);
141885ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    }
141895ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  }
141905ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
141915ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  uint32_t result = pos;
1419257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  PropertyDetails no_details = PropertyDetails(NONE, NORMAL, 0);
141935ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  while (undefs > 0) {
14194496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
14195496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org      // Adding an entry with the key beyond smi-range requires
14196496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org      // allocation. Bailout.
14197e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      return bailout;
14198496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    }
14199e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    HandleScope scope(isolate);
14200e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
14201e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org        new_dict, pos, isolate->factory()->undefined_value(), no_details);
14202e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(result.is_identical_to(new_dict));
14203e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    USE(result);
142045ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    pos++;
142055ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    undefs--;
142065ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  }
142075ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
14208e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  object->set_elements(*new_dict);
142095ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
14210e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  AllowHeapAllocation allocate_return_value;
14211e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return isolate->factory()->NewNumberFromUint(result);
142125ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org}
142135ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
142145ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
142155ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// Collects all defined (non-hole) and non-undefined (array) elements at
142165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// the start of the elements array.
142175ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// If the object is in dictionary mode, it is converted to fast elements
142185ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// mode.
14219ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.orgHandle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object,
14220ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org                                                uint32_t limit) {
14221ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  Isolate* isolate = object->GetIsolate();
1422297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  if (object->HasSloppyArgumentsElements() ||
1422397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      object->map()->is_observed()) {
1422497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    return handle(Smi::FromInt(-1), isolate);
1422597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
14226c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
14227ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  if (object->HasDictionaryElements()) {
142285ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    // Convert to fast elements containing only the existing properties.
142295ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    // Ordering is irrelevant, since we are going to sort anyway.
14230ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    Handle<SeededNumberDictionary> dict(object->element_dictionary());
14231ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    if (object->IsJSArray() || dict->requires_slow_elements() ||
14232c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org        dict->max_number_key() >= limit) {
14233ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org      return JSObject::PrepareSlowElementsForSort(object, limit);
142345ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    }
142355ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    // Convert to fast elements.
142365ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
14237ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    Handle<Map> new_map =
14238ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org        JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS);
1423940b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
14240ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ?
14241ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org        NOT_TENURED: TENURED;
14242ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    Handle<FixedArray> fast_elements =
14243ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org        isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure);
14244ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    dict->CopyValuesTo(*fast_elements);
1424549ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org    JSObject::ValidateElements(object);
1424640b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org
1424763a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org    JSObject::SetMapAndElements(object, new_map, fast_elements);
14248895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  } else if (object->HasExternalArrayElements() ||
14249895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org             object->HasFixedTypedArrayElements()) {
14250895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    // Typed arrays cannot have holes or undefined elements.
14251ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    return handle(Smi::FromInt(
14252895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        FixedArrayBase::cast(object->elements())->length()), isolate);
14253ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  } else if (!object->HasFastDoubleElements()) {
14254b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    EnsureWritableFastElements(object);
142555ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  }
14256e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object->HasFastSmiOrObjectElements() ||
14257ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org         object->HasFastDoubleElements());
142585ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
142595ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  // Collect holes at the end, undefined before that and the rest at the
142605ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  // start, and return the number of non-hole, non-undefined values.
142615ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
14262ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  Handle<FixedArrayBase> elements_base(object->elements());
14263d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org  uint32_t elements_length = static_cast<uint32_t>(elements_base->length());
142645ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  if (limit > elements_length) {
142655ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    limit = elements_length ;
142665ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  }
142675ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  if (limit == 0) {
14268ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    return handle(Smi::FromInt(0), isolate);
142695ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  }
142705ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
14271d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org  uint32_t result = 0;
14272ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  if (elements_base->map() == isolate->heap()->fixed_double_array_map()) {
14273ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    FixedDoubleArray* elements = FixedDoubleArray::cast(*elements_base);
14274d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    // Split elements into defined and the_hole, in that order.
14275d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    unsigned int holes = limit;
14276d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    // Assume most arrays contain no holes and undefined values, so minimize the
14277d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    // number of stores of non-undefined, non-the-hole values.
14278d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    for (unsigned int i = 0; i < holes; i++) {
14279d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      if (elements->is_the_hole(i)) {
14280d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org        holes--;
14281d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      } else {
14282d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org        continue;
14283d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      }
14284d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      // Position i needs to be filled.
14285d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      while (holes > i) {
14286d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org        if (elements->is_the_hole(holes)) {
14287d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org          holes--;
14288d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org        } else {
142897c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org          elements->set(i, elements->get_scalar(holes));
14290d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org          break;
14291d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org        }
14292d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      }
142935ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    }
14294d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    result = holes;
14295d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    while (holes < limit) {
14296d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      elements->set_the_hole(holes);
14297d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      holes++;
14298d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    }
14299d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org  } else {
14300ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org    FixedArray* elements = FixedArray::cast(*elements_base);
1430179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
14302d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org
14303d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    // Split elements into defined, undefined and the_hole, in that order.  Only
14304d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    // count locations for undefined and the hole, and fill them afterwards.
1430579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_gc);
14306d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    unsigned int undefs = limit;
14307d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    unsigned int holes = limit;
14308d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    // Assume most arrays contain no holes and undefined values, so minimize the
14309d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    // number of stores of non-undefined, non-the-hole values.
14310d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    for (unsigned int i = 0; i < undefs; i++) {
14311d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      Object* current = elements->get(i);
143125ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      if (current->IsTheHole()) {
143135ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org        holes--;
143145ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org        undefs--;
143155ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      } else if (current->IsUndefined()) {
143165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org        undefs--;
143175ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      } else {
14318d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org        continue;
14319d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      }
14320d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      // Position i needs to be filled.
14321d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      while (undefs > i) {
14322d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org        current = elements->get(undefs);
14323d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org        if (current->IsTheHole()) {
14324d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org          holes--;
14325d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org          undefs--;
14326d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org        } else if (current->IsUndefined()) {
14327d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org          undefs--;
14328d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org        } else {
14329d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org          elements->set(i, current, write_barrier);
14330d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org          break;
14331d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org        }
143325ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org      }
143335ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org    }
14334d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    result = undefs;
14335d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    while (undefs < holes) {
14336d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      elements->set_undefined(undefs);
14337d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      undefs++;
14338d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    }
14339d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    while (holes < limit) {
14340d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      elements->set_the_hole(holes);
14341d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      holes++;
14342d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    }
143435ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  }
143445ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
14345ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  return isolate->factory()->NewNumberFromUint(result);
143465ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org}
143475ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
14348e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
14349f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgExternalArrayType JSTypedArray::type() {
14350f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  switch (elements()->map()->instance_type()) {
14351af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size)            \
14352af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_##TYPE##_ARRAY_TYPE:                                        \
14353895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    case FIXED_##TYPE##_ARRAY_TYPE:                                           \
14354af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      return kExternal##Type##Array;
14355af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
14356af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE)
14357af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef INSTANCE_TYPE_TO_ARRAY_TYPE
14358af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
14359f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    default:
14360895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      UNREACHABLE();
14361f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      return static_cast<ExternalArrayType>(-1);
14362f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }
14363f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
14364f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
143655ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
1436657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.orgsize_t JSTypedArray::element_size() {
1436757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  switch (elements()->map()->instance_type()) {
14368af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#define INSTANCE_TYPE_TO_ELEMENT_SIZE(Type, type, TYPE, ctype, size)          \
14369af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case EXTERNAL_##TYPE##_ARRAY_TYPE:                                        \
14370af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      return size;
14371af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
14372af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    TYPED_ARRAYS(INSTANCE_TYPE_TO_ELEMENT_SIZE)
14373af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org#undef INSTANCE_TYPE_TO_ELEMENT_SIZE
14374af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
1437557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    default:
1437657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      UNREACHABLE();
1437757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      return 0;
1437857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
1437957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org}
1438057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
1438157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
14382e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgHandle<Object> ExternalUint8ClampedArray::SetValue(
14383e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<ExternalUint8ClampedArray> array,
14384e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    uint32_t index,
14385e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<Object> value) {
143860b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  uint8_t clamped_value = 0;
14387e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (index < static_cast<uint32_t>(array->length())) {
143880b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    if (value->IsSmi()) {
14389e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      int int_value = Handle<Smi>::cast(value)->value();
143900b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      if (int_value < 0) {
143910b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org        clamped_value = 0;
143920b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      } else if (int_value > 255) {
143930b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org        clamped_value = 255;
143940b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      } else {
143950b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org        clamped_value = static_cast<uint8_t>(int_value);
143960b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      }
143970b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    } else if (value->IsHeapNumber()) {
14398e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      double double_value = Handle<HeapNumber>::cast(value)->value();
143990b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      if (!(double_value > 0)) {
144000b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org        // NaN and less than zero clamp to zero.
144010b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org        clamped_value = 0;
144020b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      } else if (double_value > 255) {
144030b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org        // Greater than 255 clamp to 255.
144040b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org        clamped_value = 255;
144050b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      } else {
144060b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org        // Other doubles are rounded to the nearest integer.
1440746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        clamped_value = static_cast<uint8_t>(lrint(double_value));
144080b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      }
144090b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    } else {
144100b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      // Clamp undefined to zero (default). All other types have been
144110b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      // converted to a number type further up in the call chain.
14412e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(value->IsUndefined());
144130b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    }
14414e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    array->set(index, clamped_value);
144150b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  }
14416e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return handle(Smi::FromInt(clamped_value), array->GetIsolate());
144170b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org}
144180b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
144190b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
14420e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgtemplate<typename ExternalArrayClass, typename ValueType>
14421e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgstatic Handle<Object> ExternalArrayIntSetter(
14422e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Isolate* isolate,
14423e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    Handle<ExternalArrayClass> receiver,
14424af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    uint32_t index,
14425af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    Handle<Object> value) {
144263811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  ValueType cast_value = 0;
144273811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  if (index < static_cast<uint32_t>(receiver->length())) {
144283811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    if (value->IsSmi()) {
14429e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      int int_value = Handle<Smi>::cast(value)->value();
144303811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      cast_value = static_cast<ValueType>(int_value);
144313811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    } else if (value->IsHeapNumber()) {
14432e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      double double_value = Handle<HeapNumber>::cast(value)->value();
144333811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      cast_value = static_cast<ValueType>(DoubleToInt32(double_value));
144343811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    } else {
144353811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      // Clamp undefined to zero (default). All other types have been
144363811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      // converted to a number type further up in the call chain.
14437e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(value->IsUndefined());
144383811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
144393811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    receiver->set(index, cast_value);
144403811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  }
14441e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return isolate->factory()->NewNumberFromInt(cast_value);
144423811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
144433811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
144443811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
14445af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.orgHandle<Object> ExternalInt8Array::SetValue(Handle<ExternalInt8Array> array,
14446b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                           uint32_t index,
14447b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                           Handle<Object> value) {
14448e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return ExternalArrayIntSetter<ExternalInt8Array, int8_t>(
14449e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      array->GetIsolate(), array, index, value);
14450b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org}
14451b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
14452b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
14453e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgHandle<Object> ExternalUint8Array::SetValue(Handle<ExternalUint8Array> array,
14454e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                            uint32_t index,
14455e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                            Handle<Object> value) {
14456e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return ExternalArrayIntSetter<ExternalUint8Array, uint8_t>(
14457e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      array->GetIsolate(), array, index, value);
144583811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
144593811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
144603811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
14461e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgHandle<Object> ExternalInt16Array::SetValue(Handle<ExternalInt16Array> array,
14462e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                            uint32_t index,
14463e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                            Handle<Object> value) {
14464e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return ExternalArrayIntSetter<ExternalInt16Array, int16_t>(
14465e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      array->GetIsolate(), array, index, value);
14466b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org}
14467b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
14468b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
14469e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgHandle<Object> ExternalUint16Array::SetValue(Handle<ExternalUint16Array> array,
14470e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                             uint32_t index,
14471e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                             Handle<Object> value) {
14472e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return ExternalArrayIntSetter<ExternalUint16Array, uint16_t>(
14473e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      array->GetIsolate(), array, index, value);
144743811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
144753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
144763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
14477af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.orgHandle<Object> ExternalInt32Array::SetValue(Handle<ExternalInt32Array> array,
14478e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                            uint32_t index,
14479e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                            Handle<Object> value) {
14480e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return ExternalArrayIntSetter<ExternalInt32Array, int32_t>(
14481e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      array->GetIsolate(), array, index, value);
144823811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
144833811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
144843811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
14485af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.orgHandle<Object> ExternalUint32Array::SetValue(
14486af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    Handle<ExternalUint32Array> array,
14487b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    uint32_t index,
14488b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<Object> value) {
144893811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  uint32_t cast_value = 0;
14490e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (index < static_cast<uint32_t>(array->length())) {
144913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    if (value->IsSmi()) {
14492e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      int int_value = Handle<Smi>::cast(value)->value();
144933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      cast_value = static_cast<uint32_t>(int_value);
144943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    } else if (value->IsHeapNumber()) {
14495e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      double double_value = Handle<HeapNumber>::cast(value)->value();
144963811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      cast_value = static_cast<uint32_t>(DoubleToUint32(double_value));
144973811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    } else {
144983811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      // Clamp undefined to zero (default). All other types have been
144993811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      // converted to a number type further up in the call chain.
14500e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(value->IsUndefined());
145013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
14502e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    array->set(index, cast_value);
145033811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  }
14504e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return array->GetIsolate()->factory()->NewNumberFromUint(cast_value);
145053811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
145063811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
145073811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
14508af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.orgHandle<Object> ExternalFloat32Array::SetValue(
14509af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    Handle<ExternalFloat32Array> array,
14510af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    uint32_t index,
14511af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    Handle<Object> value) {
145125de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  float cast_value = static_cast<float>(base::OS::nan_value());
14513e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (index < static_cast<uint32_t>(array->length())) {
145143811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    if (value->IsSmi()) {
14515e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      int int_value = Handle<Smi>::cast(value)->value();
145163811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      cast_value = static_cast<float>(int_value);
145173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    } else if (value->IsHeapNumber()) {
14518e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      double double_value = Handle<HeapNumber>::cast(value)->value();
145193811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      cast_value = static_cast<float>(double_value);
145203811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    } else {
1452156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org      // Clamp undefined to NaN (default). All other types have been
145223811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org      // converted to a number type further up in the call chain.
14523e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(value->IsUndefined());
145243811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org    }
14525e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    array->set(index, cast_value);
145263811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  }
14527e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return array->GetIsolate()->factory()->NewNumber(cast_value);
145283811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
145293811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
145303811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
14531af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.orgHandle<Object> ExternalFloat64Array::SetValue(
14532af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    Handle<ExternalFloat64Array> array,
14533af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    uint32_t index,
14534af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    Handle<Object> value) {
145355de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  double double_value = base::OS::nan_value();
14536e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (index < static_cast<uint32_t>(array->length())) {
14537e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    if (value->IsNumber()) {
14538e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      double_value = value->Number();
145393847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    } else {
1454056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org      // Clamp undefined to NaN (default). All other types have been
145413847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com      // converted to a number type further up in the call chain.
14542e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(value->IsUndefined());
145433847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    }
14544e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    array->set(index, double_value);
145453847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  }
14546e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return array->GetIsolate()->factory()->NewNumber(double_value);
145473847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com}
145483847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
145493847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
14550057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgHandle<PropertyCell> JSGlobalObject::EnsurePropertyCell(
14551057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    Handle<JSGlobalObject> global,
14552e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    Handle<Name> name) {
14553e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!global->HasFastProperties());
14554f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  int entry = global->property_dictionary()->FindEntry(name);
14555750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (entry == NameDictionary::kNotFound) {
14556e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    Isolate* isolate = global->GetIsolate();
14557e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(
14558e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org        isolate->factory()->the_hole_value());
1455957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    PropertyDetails details(NONE, NORMAL, 0);
14560defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    details = details.AsDeleted();
14561f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<NameDictionary> dictionary = NameDictionary::Add(
14562e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org        handle(global->property_dictionary()), name, cell, details);
14563e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    global->set_properties(*dictionary);
14564defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org    return cell;
14565defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  } else {
14566e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    Object* value = global->property_dictionary()->ValueAt(entry);
14567e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(value->IsPropertyCell());
14568e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    return handle(PropertyCell::cast(value));
14569defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org  }
14570defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org}
14571defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
14572defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
145734a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org// This class is used for looking up two character strings in the string table.
145746141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org// If we don't have a hit we don't want to waste much time so we unroll the
145756141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org// string hash calculation loop here for speed.  Doesn't work if the two
145766141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org// characters form a decimal integer, since such strings have a different hash
145776141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org// algorithm.
145786141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.orgclass TwoCharHashTableKey : public HashTableKey {
145796141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org public:
14580a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  TwoCharHashTableKey(uint16_t c1, uint16_t c2, uint32_t seed)
145816141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    : c1_(c1), c2_(c2) {
145826141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    // Char 1.
14583fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    uint32_t hash = seed;
14584fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    hash += c1;
14585fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    hash += hash << 10;
145866141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    hash ^= hash >> 6;
145876141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    // Char 2.
145886141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    hash += c2;
145896141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    hash += hash << 10;
145906141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    hash ^= hash >> 6;
145916141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    // GetHash.
145926141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    hash += hash << 3;
145936141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    hash ^= hash >> 11;
145946141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    hash += hash << 15;
1459589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    if ((hash & String::kHashBitMask) == 0) hash = StringHasher::kZeroHash;
14596a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    hash_ = hash;
145976141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org#ifdef DEBUG
145986141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    // If this assert fails then we failed to reproduce the two-character
145996141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    // version of the string hashing algorithm above.  One reason could be
146006141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    // that we were passed two digits as characters, since the hash
146016141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    // algorithm is different in that case.
14602a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    uint16_t chars[2] = {c1, c2};
14603a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    uint32_t check_hash = StringHasher::HashSequentialString(chars, 2, seed);
14604a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    hash = (hash << String::kHashShift) | String::kIsNotArrayIndexMask;
14605e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK_EQ(static_cast<int32_t>(hash), static_cast<int32_t>(check_hash));
146066141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org#endif
146076141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  }
146086141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org
14609ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  bool IsMatch(Object* o) OVERRIDE {
146106141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    if (!o->IsString()) return false;
146116141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    String* other = String::cast(o);
146126141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    if (other->length() != 2) return false;
146136141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    if (other->Get(0) != c1_) return false;
146146141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    return other->Get(1) == c2_;
146156141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  }
146166141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org
14617ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  uint32_t Hash() OVERRIDE { return hash_; }
14618ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  uint32_t HashForObject(Object* key) OVERRIDE {
146196141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    if (!key->IsString()) return 0;
146206141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    return String::cast(key)->Hash();
146216141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  }
146226141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org
14623ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  Handle<Object> AsHandle(Isolate* isolate) OVERRIDE {
146244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    // The TwoCharHashTableKey is only used for looking in the string
146256141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    // table, not for adding to it.
146266141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org    UNREACHABLE();
14627865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    return MaybeHandle<Object>().ToHandleChecked();
146286141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  }
14629e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
146306141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org private:
14631a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  uint16_t c1_;
14632a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  uint16_t c2_;
146336141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  uint32_t hash_;
146346141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org};
146356141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org
146366141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org
14637a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgMaybeHandle<String> StringTable::InternalizeStringIfExists(
14638a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    Isolate* isolate,
14639a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    Handle<String> string) {
14640a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (string->IsInternalizedString()) {
14641a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    return string;
14642a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  }
14643a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  return LookupStringIfExists(isolate, string);
14644a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org}
14645a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
14646a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
14647a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgMaybeHandle<String> StringTable::LookupStringIfExists(
14648a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    Isolate* isolate,
14649a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    Handle<String> string) {
14650a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  Handle<StringTable> string_table = isolate->factory()->string_table();
14651a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  InternalizedStringKey key(string);
14652a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  int entry = string_table->FindEntry(&key);
146532abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  if (entry == kNotFound) {
14654a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    return MaybeHandle<String>();
146557c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  } else {
14656a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate);
14657e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(StringShape(*result).IsInternalized());
14658a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    return result;
146597c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  }
146607c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org}
146617c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
146627c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
14663a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgMaybeHandle<String> StringTable::LookupTwoCharsStringIfExists(
14664a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    Isolate* isolate,
14665a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    uint16_t c1,
14666a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    uint16_t c2) {
14667a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  Handle<StringTable> string_table = isolate->factory()->string_table();
14668a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  TwoCharHashTableKey key(c1, c2, isolate->heap()->HashSeed());
14669a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  int entry = string_table->FindEntry(&key);
146706141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  if (entry == kNotFound) {
14671a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    return MaybeHandle<String>();
146726141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  } else {
14673a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate);
14674e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(StringShape(*result).IsInternalized());
14675a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    return result;
146766141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org  }
146776141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org}
146786141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org
146796141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org
14680b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.orgHandle<String> StringTable::LookupString(Isolate* isolate,
14681b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org                                         Handle<String> string) {
14682b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  InternalizedStringKey key(string);
14683b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  return LookupKey(isolate, &key);
14684b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org}
14685b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
14686b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
14687b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.orgHandle<String> StringTable::LookupKey(Isolate* isolate, HashTableKey* key) {
14688b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  Handle<StringTable> table = isolate->factory()->string_table();
14689b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  int entry = table->FindEntry(key);
1469043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
146914a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // String already in table.
146922abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  if (entry != kNotFound) {
14693b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org    return handle(String::cast(table->KeyAt(entry)), isolate);
1469443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1469543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
146964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Adding new string. Grow table if needed.
14697b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  table = StringTable::EnsureCapacity(table, 1, key);
1469843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
146994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Create string object.
14700b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  Handle<Object> string = key->AsHandle(isolate);
14701f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // There must be no attempts to internalize strings that could throw
14702f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // InvalidStringLength error.
14703f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CHECK(!string.is_null());
1470443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
147054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Add the new string and return it along with the string table.
1470686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  entry = table->FindInsertionEntry(key->Hash());
14707b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  table->set(EntryToIndex(entry), *string);
1470843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  table->ElementAdded();
14709b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
14710b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  isolate->factory()->set_string_table(table);
14711b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  return Handle<String>::cast(string);
1471243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1471343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1471443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
147159e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgHandle<Object> CompilationCacheTable::Lookup(Handle<String> src,
147169e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                             Handle<Context> context) {
147179e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Isolate* isolate = GetIsolate();
147189e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<SharedFunctionInfo> shared(context->closure()->shared());
147199e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  StringSharedKey key(src, shared, FLAG_use_strict ? STRICT : SLOPPY,
14720355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                      RelocInfo::kNoPosition);
147219258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  int entry = FindEntry(&key);
147229e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  if (entry == kNotFound) return isolate->factory()->undefined_value();
147239e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
147249258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
147259258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
147269258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
14727040b51669fc15f81ef4aab890e004c957a896560yangguo@chromium.orgHandle<Object> CompilationCacheTable::LookupEval(
14728040b51669fc15f81ef4aab890e004c957a896560yangguo@chromium.org    Handle<String> src, Handle<SharedFunctionInfo> outer_info,
14729040b51669fc15f81ef4aab890e004c957a896560yangguo@chromium.org    StrictMode strict_mode, int scope_position) {
147309e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Isolate* isolate = GetIsolate();
14731040b51669fc15f81ef4aab890e004c957a896560yangguo@chromium.org  // Cache key is the tuple (source, outer shared function info, scope position)
14732040b51669fc15f81ef4aab890e004c957a896560yangguo@chromium.org  // to unambiguously identify the context chain the cached eval code assumes.
14733040b51669fc15f81ef4aab890e004c957a896560yangguo@chromium.org  StringSharedKey key(src, outer_info, strict_mode, scope_position);
14734381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  int entry = FindEntry(&key);
147359e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  if (entry == kNotFound) return isolate->factory()->undefined_value();
147369e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
14737381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org}
14738381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
14739381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
147409e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgHandle<Object> CompilationCacheTable::LookupRegExp(Handle<String> src,
147419e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                                                   JSRegExp::Flags flags) {
147429e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Isolate* isolate = GetIsolate();
147439e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  DisallowHeapAllocation no_allocation;
147449fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  RegExpKey key(src, flags);
147459fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  int entry = FindEntry(&key);
147469e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  if (entry == kNotFound) return isolate->factory()->undefined_value();
147479e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
147489fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org}
147499fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
147509fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
147519e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgHandle<CompilationCacheTable> CompilationCacheTable::Put(
147529e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Handle<CompilationCacheTable> cache, Handle<String> src,
147539e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Handle<Context> context, Handle<Object> value) {
147549e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Isolate* isolate = cache->GetIsolate();
147559e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<SharedFunctionInfo> shared(context->closure()->shared());
147569e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  StringSharedKey key(src, shared, FLAG_use_strict ? STRICT : SLOPPY,
14757355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                      RelocInfo::kNoPosition);
147589fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  cache = EnsureCapacity(cache, 1, &key);
14759865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Handle<Object> k = key.AsHandle(isolate);
1476086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  int entry = cache->FindInsertionEntry(key.Hash());
147619e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  cache->set(EntryToIndex(entry), *k);
147629e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  cache->set(EntryToIndex(entry) + 1, *value);
147639258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  cache->ElementAdded();
147649258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  return cache;
147659258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
147669258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
147679258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
147689e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgHandle<CompilationCacheTable> CompilationCacheTable::PutEval(
147699e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    Handle<CompilationCacheTable> cache, Handle<String> src,
14770040b51669fc15f81ef4aab890e004c957a896560yangguo@chromium.org    Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value,
147719e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org    int scope_position) {
147729e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Isolate* isolate = cache->GetIsolate();
14773040b51669fc15f81ef4aab890e004c957a896560yangguo@chromium.org  StringSharedKey key(src, outer_info, value->strict_mode(), scope_position);
147749fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  cache = EnsureCapacity(cache, 1, &key);
14775865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Handle<Object> k = key.AsHandle(isolate);
1477686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  int entry = cache->FindInsertionEntry(key.Hash());
147779e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  cache->set(EntryToIndex(entry), *k);
147789e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  cache->set(EntryToIndex(entry) + 1, *value);
14779381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  cache->ElementAdded();
14780381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  return cache;
14781381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org}
14782381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
14783381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
147849e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgHandle<CompilationCacheTable> CompilationCacheTable::PutRegExp(
147859e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      Handle<CompilationCacheTable> cache, Handle<String> src,
147869e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      JSRegExp::Flags flags, Handle<FixedArray> value) {
147879fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  RegExpKey key(src, flags);
147889fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  cache = EnsureCapacity(cache, 1, &key);
1478986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  int entry = cache->FindInsertionEntry(key.Hash());
147909d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // We store the value in the key slot, and compare the search key
147919d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // to the stored value with a custon IsMatch function during lookups.
147929e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  cache->set(EntryToIndex(entry), *value);
147939e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  cache->set(EntryToIndex(entry) + 1, *value);
147949fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  cache->ElementAdded();
147959fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org  return cache;
147969fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org}
147979fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
147989fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org
14799a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid CompilationCacheTable::Remove(Object* value) {
148009e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  DisallowHeapAllocation no_allocation;
14801c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Object* the_hole_value = GetHeap()->the_hole_value();
14802a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int entry = 0, size = Capacity(); entry < size; entry++) {
14803a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    int entry_index = EntryToIndex(entry);
14804a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    int value_index = entry_index + 1;
14805a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (get(value_index) == value) {
14806c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      NoWriteBarrierSet(this, entry_index, the_hole_value);
14807c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      NoWriteBarrierSet(this, value_index, the_hole_value);
14808a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ElementRemoved();
14809a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
14810a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
14811a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return;
14812a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
14813a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
14814a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
14815750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org// StringsKey used for HashTable where key is array of internalized strings.
148164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgclass StringsKey : public HashTableKey {
14817236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org public:
148189fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  explicit StringsKey(Handle<FixedArray> strings) : strings_(strings) { }
14819236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
14820ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  bool IsMatch(Object* strings) OVERRIDE {
148214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    FixedArray* o = FixedArray::cast(strings);
148224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    int len = strings_->length();
14823236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    if (o->length() != len) return false;
14824236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    for (int i = 0; i < len; i++) {
148254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      if (o->get(i) != strings_->get(i)) return false;
14826236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    }
14827236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    return true;
14828236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
14829236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
14830ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  uint32_t Hash() OVERRIDE { return HashForObject(*strings_); }
14831236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
14832ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  uint32_t HashForObject(Object* obj) OVERRIDE {
148334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    FixedArray* strings = FixedArray::cast(obj);
148344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    int len = strings->length();
148355a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org    uint32_t hash = 0;
14836236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    for (int i = 0; i < len; i++) {
148374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      hash ^= String::cast(strings->get(i))->Hash();
14838236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    }
14839236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    return hash;
14840236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
14841236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
14842ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  Handle<Object> AsHandle(Isolate* isolate) OVERRIDE { return strings_; }
14843236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
148445a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org private:
148459fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<FixedArray> strings_;
14846236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org};
14847236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
148485a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org
14849236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.orgObject* MapCache::Lookup(FixedArray* array) {
148509fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  DisallowHeapAllocation no_alloc;
148519fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  StringsKey key(handle(array));
14852236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  int entry = FindEntry(&key);
14853c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (entry == kNotFound) return GetHeap()->undefined_value();
148545a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  return get(EntryToIndex(entry) + 1);
14855236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org}
14856236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
14857236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
148589fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgHandle<MapCache> MapCache::Put(
148599fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<MapCache> map_cache, Handle<FixedArray> array, Handle<Map> value) {
148604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  StringsKey key(array);
14861236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
148629fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<MapCache> new_cache = EnsureCapacity(map_cache, 1, &key);
148639fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int entry = new_cache->FindInsertionEntry(key.Hash());
148649fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  new_cache->set(EntryToIndex(entry), *array);
148659fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  new_cache->set(EntryToIndex(entry) + 1, *value);
148669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  new_cache->ElementAdded();
148679fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return new_cache;
14868236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org}
14869236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
14870236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
14871c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
148729fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgHandle<Derived> Dictionary<Derived, Shape, Key>::New(
148739fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Isolate* isolate,
148749fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    int at_least_space_for,
148759fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    PretenureFlag pretenure) {
14876e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(0 <= at_least_space_for);
148779fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<Derived> dict = DerivedHashTable::New(isolate,
148789fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                               at_least_space_for,
148799fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                               USE_DEFAULT_MINIMUM_CAPACITY,
148809fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org                                               pretenure);
148819fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
148829fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Initialize the next enumeration index.
148839fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
148849fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  return dict;
148859fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
148869fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
148879fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
14888c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
14889f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgvoid Dictionary<Derived, Shape, Key>::GenerateNewEnumerationIndices(
14890f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<Derived> dictionary) {
14891f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Factory* factory = dictionary->GetIsolate()->factory();
14892f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  int length = dictionary->NumberOfElements();
1489343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1489443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate and initialize iteration order array.
14895f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Handle<FixedArray> iteration_order = factory->NewFixedArray(length);
148965a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  for (int i = 0; i < length; i++) {
14897b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    iteration_order->set(i, Smi::FromInt(i));
148985a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  }
1489943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1490043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate array with enumeration order.
14901f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Handle<FixedArray> enumeration_order = factory->NewFixedArray(length);
1490243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1490343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fill the enumeration order array with property details.
14904f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  int capacity = dictionary->Capacity();
1490543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int pos = 0;
1490643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < capacity; i++) {
14907f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    if (dictionary->IsKey(dictionary->KeyAt(i))) {
14908f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      int index = dictionary->DetailsAt(i).dictionary_index();
1490906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org      enumeration_order->set(pos++, Smi::FromInt(index));
1491043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1491143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1491243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1491343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Sort the arrays wrt. enumeration order.
14914f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  iteration_order->SortPairs(*enumeration_order, enumeration_order->length());
1491543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1491643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Overwrite the enumeration_order with the enumeration indices.
1491743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < length; i++) {
1491843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int index = Smi::cast(iteration_order->get(i))->value();
1491943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    int enum_index = PropertyDetails::kInitialIndex + i;
14920b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    enumeration_order->set(index, Smi::FromInt(enum_index));
1492143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1492243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1492343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Update the dictionary with new indices.
14924f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  capacity = dictionary->Capacity();
1492543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  pos = 0;
1492643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < capacity; i++) {
14927f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    if (dictionary->IsKey(dictionary->KeyAt(i))) {
1492843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      int enum_index = Smi::cast(enumeration_order->get(pos++))->value();
14929f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      PropertyDetails details = dictionary->DetailsAt(i);
14930f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      PropertyDetails new_details = PropertyDetails(
1493157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          details.attributes(), details.type(), enum_index);
14932f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      dictionary->DetailsAtPut(i, new_details);
1493343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1493443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1493543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1493643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Set the next enumeration index.
14937f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length);
1493843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1493943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14940f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org
14941c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
14942f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Derived> Dictionary<Derived, Shape, Key>::EnsureCapacity(
14943f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<Derived> dictionary, int n, Key key) {
149449a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Check whether there are enough enumeration indices to add n elements.
1494586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  if (Shape::kIsEnumerable &&
14946f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      !PropertyDetails::IsValidIndex(dictionary->NextEnumerationIndex() + n)) {
1494743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // If not, we generate new indices for the properties.
14948f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    GenerateNewEnumerationIndices(dictionary);
1494943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
14950f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DerivedHashTable::EnsureCapacity(dictionary, n, key);
149519fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org}
149529fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
149539fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
14954c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
14955c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgHandle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty(
14956865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    Handle<Derived> dictionary,
149575b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    int entry,
149585b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    JSObject::DeleteMode mode) {
14959865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Factory* factory = dictionary->GetIsolate()->factory();
14960865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  PropertyDetails details = dictionary->DetailsAt(entry);
14961e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  // Ignore attributes if forcing a deletion.
14962f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org  if (!details.IsConfigurable() && mode != JSReceiver::FORCE_DELETION) {
14963865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    return factory->false_value();
14964e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  }
14965865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org
14966865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  dictionary->SetEntry(
14967865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org      entry, factory->the_hole_value(), factory->the_hole_value());
14968865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  dictionary->ElementRemoved();
14969865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  return factory->true_value();
1497043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1497143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1497243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14973c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
14974f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Derived> Dictionary<Derived, Shape, Key>::AtPut(
14975f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<Derived> dictionary, Key key, Handle<Object> value) {
14976f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  int entry = dictionary->FindEntry(key);
1497743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1497843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the entry is present set the value;
14979c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  if (entry != Dictionary::kNotFound) {
14980f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    dictionary->ValueAtPut(entry, *value);
14981f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    return dictionary;
1498243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1498343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1498443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check whether the dictionary should be extended.
14985f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  dictionary = EnsureCapacity(dictionary, 1, key);
14986a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org#ifdef DEBUG
14987a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  USE(Shape::AsHandle(dictionary->GetIsolate(), key));
14988a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org#endif
1498957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  PropertyDetails details = PropertyDetails(NONE, NORMAL, 0);
14990f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
14991865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  AddEntry(dictionary, key, value, details, dictionary->Hash(key));
14992865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  return dictionary;
1499343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1499443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1499543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14996c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
14997f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Derived> Dictionary<Derived, Shape, Key>::Add(
14998f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<Derived> dictionary,
14999c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    Key key,
15000f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<Object> value,
15001c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    PropertyDetails details) {
1500286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // Valdate key is absent.
15003e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  SLOW_DCHECK((dictionary->FindEntry(key) == Dictionary::kNotFound));
1500443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check whether the dictionary should be extended.
15005f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  dictionary = EnsureCapacity(dictionary, 1, key);
15006f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
15007865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  AddEntry(dictionary, key, value, details, dictionary->Hash(key));
15008865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  return dictionary;
1500943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1501043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1501143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1501243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Add a key, value pair to the dictionary.
15013c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
15014865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.orgvoid Dictionary<Derived, Shape, Key>::AddEntry(
15015f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<Derived> dictionary,
15016f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Key key,
15017f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<Object> value,
15018f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    PropertyDetails details,
15019f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    uint32_t hash) {
1502086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // Compute the key object.
15021865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  Handle<Object> k = Shape::AsHandle(dictionary->GetIsolate(), key);
1502286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
15023865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  uint32_t entry = dictionary->FindInsertionEntry(hash);
1502443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Insert element at empty or deleted entry
1502546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (!details.IsDeleted() &&
1502606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org      details.dictionary_index() == 0 &&
1502706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org      Shape::kIsEnumerable) {
1502843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Assign an enumeration index to the property and update
1502943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // SetNextEnumerationIndex.
15030865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    int index = dictionary->NextEnumerationIndex();
1503157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    details = PropertyDetails(details.attributes(), details.type(), index);
15032865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    dictionary->SetNextEnumerationIndex(index + 1);
1503343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
15034865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  dictionary->SetEntry(entry, k, value, details);
15035e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((dictionary->KeyAt(entry)->IsNumber() ||
15036865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org          dictionary->KeyAt(entry)->IsName()));
15037865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  dictionary->ElementAdded();
1503843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1503943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1504043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15041f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) {
15042f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  DisallowHeapAllocation no_allocation;
1504343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the dictionary requires slow elements an element has already
1504443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // been added at a high index.
1504543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (requires_slow_elements()) return;
1504643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if this index is high enough that we should require slow
1504743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // elements.
1504843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (key > kRequiresSlowElementsLimit) {
15049bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    set_requires_slow_elements();
1505043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
1505143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1505243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Update max key value.
150535a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  Object* max_index_object = get(kMaxNumberKeyIndex);
1505443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!max_index_object->IsSmi() || max_number_key() < key) {
1505586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org    FixedArray::set(kMaxNumberKeyIndex,
15056b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                    Smi::FromInt(key << kRequiresSlowElementsTagSize));
1505743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1505843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1505943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15060f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org
15061b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgHandle<SeededNumberDictionary> SeededNumberDictionary::AddNumberEntry(
15062b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<SeededNumberDictionary> dictionary,
15063b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    uint32_t key,
15064b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<Object> value,
15065b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    PropertyDetails details) {
15066f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  dictionary->UpdateMaxNumberKey(key);
15067e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound);
15068f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return Add(dictionary, key, value, details);
1506943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1507043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1507143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15072f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<UnseededNumberDictionary> UnseededNumberDictionary::AddNumberEntry(
15073f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<UnseededNumberDictionary> dictionary,
15074f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    uint32_t key,
15075f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<Object> value) {
15076e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound);
15077f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return Add(dictionary, key, value, PropertyDetails(NONE, NORMAL, 0));
15078f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
15079f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
15080f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
15081f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut(
15082f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<SeededNumberDictionary> dictionary,
15083f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    uint32_t key,
15084f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<Object> value) {
15085f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  dictionary->UpdateMaxNumberKey(key);
15086f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return AtPut(dictionary, key, value);
1508743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1508843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1508943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15090f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<UnseededNumberDictionary> UnseededNumberDictionary::AtNumberPut(
15091f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<UnseededNumberDictionary> dictionary,
15092f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    uint32_t key,
15093f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<Object> value) {
15094f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return AtPut(dictionary, key, value);
15095f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
15096f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
15097f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
15098f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comHandle<SeededNumberDictionary> SeededNumberDictionary::Set(
15099f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    Handle<SeededNumberDictionary> dictionary,
15100f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    uint32_t key,
15101f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    Handle<Object> value,
15102f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    PropertyDetails details) {
15103f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  int entry = dictionary->FindEntry(key);
15104f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  if (entry == kNotFound) {
15105f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    return AddNumberEntry(dictionary, key, value, details);
15106f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  }
1510743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Preserve enumeration index.
1510843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  details = PropertyDetails(details.attributes(),
1510943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                            details.type(),
15110f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org                            dictionary->DetailsAt(entry).dictionary_index());
15111f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Handle<Object> object_key =
15112f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      SeededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key);
15113865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  dictionary->SetEntry(entry, object_key, value, details);
15114f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return dictionary;
1511543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1511643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1511743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15118f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<UnseededNumberDictionary> UnseededNumberDictionary::Set(
15119f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<UnseededNumberDictionary> dictionary,
15120f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    uint32_t key,
15121f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    Handle<Object> value) {
15122f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  int entry = dictionary->FindEntry(key);
15123f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  if (entry == kNotFound) return AddNumberEntry(dictionary, key, value);
15124f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Handle<Object> object_key =
15125f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      UnseededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key);
15126865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  dictionary->SetEntry(entry, object_key, value);
15127f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return dictionary;
15128f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com}
15129f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
15130f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
15131bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
15132c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
15133c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgint Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes(
1513486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org    PropertyAttributes filter) {
15135c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  int capacity = DerivedHashTable::Capacity();
1513643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int result = 0;
1513743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < capacity; i++) {
15138c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    Object* k = DerivedHashTable::KeyAt(i);
15139c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) {
15140defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      PropertyDetails details = DetailsAt(i);
15141defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      if (details.IsDeleted()) continue;
15142defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      PropertyAttributes attr = details.attributes();
1514343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if ((attr & filter) == 0) result++;
1514443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1514543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1514643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
1514743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1514843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1514943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15150c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
15151c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgint Dictionary<Derived, Shape, Key>::NumberOfEnumElements() {
1515243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return NumberOfElementsFilterAttributes(
15153381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org      static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC));
1515443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1515543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1515643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15157c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
15158c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgvoid Dictionary<Derived, Shape, Key>::CopyKeysTo(
151596db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    FixedArray* storage,
151606db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    PropertyAttributes filter,
15161c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) {
15162e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter));
15163c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  int capacity = DerivedHashTable::Capacity();
1516443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index = 0;
1516543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < capacity; i++) {
15166c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org     Object* k = DerivedHashTable::KeyAt(i);
15167c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org     if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) {
15168defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org       PropertyDetails details = DetailsAt(i);
15169defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org       if (details.IsDeleted()) continue;
15170defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org       PropertyAttributes attr = details.attributes();
1517143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       if ((attr & filter) == 0) storage->set(index++, k);
1517243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen     }
1517343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
15174c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  if (sort_mode == Dictionary::SORTED) {
151756db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    storage->SortPairs(storage, index);
151766db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  }
15177e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(storage->length() >= index);
1517843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1517943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1518043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15181381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.orgstruct EnumIndexComparator {
15182381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { }
15183381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  bool operator() (Smi* a, Smi* b) {
15184381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org    PropertyDetails da(dict->DetailsAt(a->value()));
15185381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org    PropertyDetails db(dict->DetailsAt(b->value()));
15186381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org    return da.dictionary_index() < db.dictionary_index();
15187381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  }
15188381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  NameDictionary* dict;
15189381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org};
15190381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org
15191381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org
15192381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.orgvoid NameDictionary::CopyEnumKeysTo(FixedArray* storage) {
1519378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  int length = storage->length();
1519443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int capacity = Capacity();
1519578502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  int properties = 0;
1519643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < capacity; i++) {
1519743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen     Object* k = KeyAt(i);
15198750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org     if (IsKey(k) && !k->IsSymbol()) {
1519943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen       PropertyDetails details = DetailsAt(i);
15200defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org       if (details.IsDeleted() || details.IsDontEnum()) continue;
15201381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org       storage->set(properties, Smi::FromInt(i));
1520278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org       properties++;
1520378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org       if (properties == length) break;
1520443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen     }
1520543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
15206e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  CHECK_EQ(length, properties);
15207381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  EnumIndexComparator cmp(this);
15208381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress());
15209381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  std::sort(start, start + length, cmp);
15210381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  for (int i = 0; i < length; i++) {
15211381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org    int index = Smi::cast(storage->get(i))->value();
15212381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org    storage->set(i, KeyAt(index));
1521378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  }
1521443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1521543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1521643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
152178a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
152188a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.orgvoid Dictionary<Derived, Shape, Key>::CopyKeysTo(
152198a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org    FixedArray* storage,
152208a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org    int index,
152218a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org    PropertyAttributes filter,
15222c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) {
15223e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter));
15224c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  int capacity = DerivedHashTable::Capacity();
1522543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < capacity; i++) {
15226c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    Object* k = DerivedHashTable::KeyAt(i);
15227c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) {
15228defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      PropertyDetails details = DetailsAt(i);
15229defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org      if (details.IsDeleted()) continue;
15230f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      PropertyAttributes attr = details.attributes();
152318a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org      if ((attr & filter) == 0) storage->set(index++, k);
1523243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1523343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
15234c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  if (sort_mode == Dictionary::SORTED) {
152358a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org    storage->SortPairs(storage, index);
152366db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  }
152378a89641487507e4209d584f03d024a6f76278c1fmachenbach@chromium.org  DCHECK(storage->length() >= index);
1523843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1523943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1524043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1524143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Backwards lookup (slow).
15242c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgtemplate<typename Derived, typename Shape, typename Key>
15243c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgObject* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) {
15244c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  int capacity = DerivedHashTable::Capacity();
1524543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < capacity; i++) {
15246c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    Object* k =  DerivedHashTable::KeyAt(i);
15247c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org    if (Dictionary::IsKey(k)) {
152482abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org      Object* e = ValueAt(i);
15249b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      if (e->IsPropertyCell()) {
15250b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        e = PropertyCell::cast(e)->value();
152512abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org      }
152522abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org      if (e == value) return k;
1525343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1525443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
15255c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org  Heap* heap = Dictionary::GetHeap();
15256ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return heap->undefined_value();
1525743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1525843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1525943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
152603484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgObject* ObjectHashTable::Lookup(Handle<Object> key) {
152613484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  DisallowHeapAllocation no_gc;
15262e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsKey(*key));
15263c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
15264394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // If the object does not have an identity hash, it was never used as a key.
15265057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Object* hash = key->GetHash();
15266057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  if (hash->IsUndefined()) {
15267057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    return GetHeap()->the_hole_value();
15268394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
152697943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  int entry = FindEntry(key);
152707a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org  if (entry == kNotFound) return GetHeap()->the_hole_value();
152717943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  return get(EntryToIndex(entry) + 1);
152727943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org}
152737943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
152747943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
15275057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgHandle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
15276057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org                                             Handle<Object> key,
15277057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org                                             Handle<Object> value) {
15278e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(table->IsKey(*key));
15279e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!value->IsTheHole());
15280057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
15281057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Isolate* isolate = table->GetIsolate();
15282c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
152837943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  // Make sure the key object has an identity hash code.
152843c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Handle<Smi> hash = Object::GetOrCreateHash(isolate, key);
15285057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
15286865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  int entry = table->FindEntry(key);
152877943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
152887943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  // Key is already in table, just overwrite value.
152897943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  if (entry != kNotFound) {
15290057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    table->set(EntryToIndex(entry) + 1, *value);
15291057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    return table;
152927943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  }
152937943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
152947943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  // Check whether the hash table should be extended.
15295865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  table = EnsureCapacity(table, 1, key);
152963c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  table->AddEntry(table->FindInsertionEntry(hash->value()),
15297057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org                  *key,
15298057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org                  *value);
152997943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  return table;
153007943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org}
153017943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
153027943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
15303196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgHandle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table,
15304196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                                                Handle<Object> key,
15305196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                                                bool* was_present) {
15306e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(table->IsKey(*key));
15307196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
15308196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  Object* hash = key->GetHash();
15309196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (hash->IsUndefined()) {
15310196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    *was_present = false;
15311196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    return table;
15312196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  }
15313196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
15314196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  int entry = table->FindEntry(key);
15315196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (entry == kNotFound) {
15316196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    *was_present = false;
15317196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    return table;
15318196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  }
15319196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
15320196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  *was_present = true;
15321196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  table->RemoveEntry(entry);
15322196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  return Shrink(table, key);
15323196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
15324196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
15325196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
15326394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid ObjectHashTable::AddEntry(int entry, Object* key, Object* value) {
153277943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  set(EntryToIndex(entry), key);
153287943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  set(EntryToIndex(entry) + 1, value);
153297943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  ElementAdded();
153307943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org}
153317943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
153327943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
15333c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid ObjectHashTable::RemoveEntry(int entry) {
15334c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  set_the_hole(EntryToIndex(entry));
15335c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  set_the_hole(EntryToIndex(entry) + 1);
153367943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org  ElementRemoved();
153377943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org}
153387943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
153397943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
153403484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgObject* WeakHashTable::Lookup(Handle<Object> key) {
153413484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  DisallowHeapAllocation no_gc;
15342e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsKey(*key));
1534325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  int entry = FindEntry(key);
1534425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  if (entry == kNotFound) return GetHeap()->the_hole_value();
1534525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  return get(EntryToValueIndex(entry));
1534625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org}
1534725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
1534825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
15349865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.orgHandle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table,
15350865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org                                         Handle<Object> key,
15351865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org                                         Handle<Object> value) {
15352e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(table->IsKey(*key));
15353865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  int entry = table->FindEntry(key);
1535425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  // Key is already in table, just overwrite value.
1535525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  if (entry != kNotFound) {
15356aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org    // TODO(ulan): Skipping write barrier is a temporary solution to avoid
15357aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org    // memory leaks. Remove this once we have special visitor for weak fixed
15358aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org    // arrays.
15359aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org    table->set(EntryToValueIndex(entry), *value, SKIP_WRITE_BARRIER);
15360865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    return table;
1536125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  }
1536225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
1536325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  // Check whether the hash table should be extended.
15364865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  table = EnsureCapacity(table, 1, key, TENURED);
15365865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org
15366865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  table->AddEntry(table->FindInsertionEntry(table->Hash(key)), key, value);
1536725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  return table;
1536825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org}
1536925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
1537025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
15371865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.orgvoid WeakHashTable::AddEntry(int entry,
15372865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org                             Handle<Object> key,
15373865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org                             Handle<Object> value) {
15374865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  DisallowHeapAllocation no_allocation;
15375aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org  // TODO(ulan): Skipping write barrier is a temporary solution to avoid
15376aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org  // memory leaks. Remove this once we have special visitor for weak fixed
15377aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org  // arrays.
15378aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org  set(EntryToIndex(entry), *key, SKIP_WRITE_BARRIER);
15379aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org  set(EntryToValueIndex(entry), *value, SKIP_WRITE_BARRIER);
1538025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  ElementAdded();
1538125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org}
1538225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
1538325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
153844ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate<class Derived, class Iterator, int entrysize>
153854ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgHandle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Allocate(
153868f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Isolate* isolate, int capacity, PretenureFlag pretenure) {
153878f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  // Capacity must be a power of two, since we depend on being able
153888f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  // to divide and multiple by 2 (kLoadFactor) to derive capacity
153898f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  // from number of buckets. If we decide to change kLoadFactor
153908f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  // to something other than 2, capacity should be stored as another
153918f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  // field of this object.
1539221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  capacity = base::bits::RoundUpToPowerOfTwo32(Max(kMinCapacity, capacity));
153938f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  if (capacity > kMaxCapacity) {
153948f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
153958f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  }
153968f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int num_buckets = capacity / kLoadFactor;
153979e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<FixedArray> backing_store = isolate->factory()->NewFixedArray(
153989e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      kHashTableStartIndex + num_buckets + (capacity * kEntrySize), pretenure);
153999e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  backing_store->set_map_no_write_barrier(
154009e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org      isolate->heap()->ordered_hash_table_map());
154019e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Handle<Derived> table = Handle<Derived>::cast(backing_store);
154028f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  for (int i = 0; i < num_buckets; ++i) {
154038f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound));
154048f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  }
154058f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  table->SetNumberOfBuckets(num_buckets);
154068f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  table->SetNumberOfElements(0);
154078f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  table->SetNumberOfDeletedElements(0);
154088f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  return table;
154098f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org}
154108f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
154118f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
154124ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate<class Derived, class Iterator, int entrysize>
154134ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgHandle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::EnsureGrowable(
154148f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Handle<Derived> table) {
15415e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!table->IsObsolete());
154166a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
154178f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int nof = table->NumberOfElements();
154188f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int nod = table->NumberOfDeletedElements();
154198f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int capacity = table->Capacity();
154208f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  if ((nof + nod) < capacity) return table;
154218f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  // Don't need to grow if we can simply clear out deleted entries instead.
154228f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  // Note that we can't compact in place, though, so we always allocate
154238f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  // a new table.
154248f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity);
154258f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org}
154268f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
154278f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
154284ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate<class Derived, class Iterator, int entrysize>
154294ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgHandle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Shrink(
154308f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Handle<Derived> table) {
15431e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!table->IsObsolete());
154326a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
154338f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int nof = table->NumberOfElements();
154348f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int capacity = table->Capacity();
154356a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  if (nof >= (capacity >> 2)) return table;
154368f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  return Rehash(table, capacity / 2);
154378f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org}
154388f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
154398f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
154404ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate<class Derived, class Iterator, int entrysize>
154414ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgHandle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear(
154424ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    Handle<Derived> table) {
15443e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!table->IsObsolete());
154446a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
154454ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  Handle<Derived> new_table =
154464ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org      Allocate(table->GetIsolate(),
154474ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org               kMinCapacity,
154484ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org               table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
154494ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
154506a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  table->SetNextTable(*new_table);
154516a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  table->SetNumberOfDeletedElements(-1);
154524ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
154534ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  return new_table;
154544ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org}
154554ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
154564ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
154574ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate<class Derived, class Iterator, int entrysize>
15458196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgHandle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Remove(
15459196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    Handle<Derived> table, Handle<Object> key, bool* was_present) {
15460196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  int entry = table->FindEntry(key);
15461196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (entry == kNotFound) {
15462196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    *was_present = false;
15463196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    return table;
15464196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  }
15465196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  *was_present = true;
15466196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  table->RemoveEntry(entry);
15467196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  return Shrink(table);
15468196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
15469196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
15470196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
15471196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgtemplate<class Derived, class Iterator, int entrysize>
154724ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgHandle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash(
154738f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Handle<Derived> table, int new_capacity) {
15474e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!table->IsObsolete());
154756a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
154768f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<Derived> new_table =
154778f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      Allocate(table->GetIsolate(),
154788f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org               new_capacity,
154798f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org               table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
154808f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int nof = table->NumberOfElements();
154818f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int nod = table->NumberOfDeletedElements();
154828f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int new_buckets = new_table->NumberOfBuckets();
154838f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int new_entry = 0;
154846a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  int removed_holes_index = 0;
154856a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
154868f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) {
154878f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Object* key = table->KeyAt(old_entry);
154886a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    if (key->IsTheHole()) {
154896a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      table->SetRemovedIndexAt(removed_holes_index++, old_entry);
154906a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      continue;
154916a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    }
154926a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
154938f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Object* hash = key->GetHash();
154948f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    int bucket = Smi::cast(hash)->value() & (new_buckets - 1);
154958f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Object* chain_entry = new_table->get(kHashTableStartIndex + bucket);
154968f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry));
154978f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    int new_index = new_table->EntryToIndex(new_entry);
154988f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    int old_index = table->EntryToIndex(old_entry);
154998f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    for (int i = 0; i < entrysize; ++i) {
155008f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      Object* value = table->get(old_index + i);
155018f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      new_table->set(new_index + i, value);
155028f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    }
155038f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    new_table->set(new_index + kChainOffset, chain_entry);
155048f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    ++new_entry;
155058f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  }
155064ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
15507e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(nod, removed_holes_index);
155084ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
155096a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  new_table->SetNumberOfElements(nof);
155106a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  table->SetNextTable(*new_table);
155114ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
155128f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  return new_table;
155138f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org}
155148f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
155158f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
1551612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgtemplate <class Derived, class Iterator, int entrysize>
155173484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgint OrderedHashTable<Derived, Iterator, entrysize>::FindEntry(
1551812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Handle<Object> key, int hash) {
15519e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsObsolete());
155206a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
155213484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  DisallowHeapAllocation no_gc;
15522e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!key->IsTheHole());
1552312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  for (int entry = HashToEntry(hash); entry != kNotFound;
155248f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org       entry = ChainAt(entry)) {
155258f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Object* candidate = KeyAt(entry);
1552679d0704c4f2ed07d3b30ee08ea1e1af79e521bd2machenbach@chromium.org    if (candidate->SameValueZero(*key))
155278f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      return entry;
155288f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  }
155298f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  return kNotFound;
155308f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org}
155318f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
155328f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
1553312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgtemplate <class Derived, class Iterator, int entrysize>
1553412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgint OrderedHashTable<Derived, Iterator, entrysize>::FindEntry(
1553512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Handle<Object> key) {
1553612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  DisallowHeapAllocation no_gc;
1553712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Object* hash = key->GetHash();
1553812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (!hash->IsSmi()) return kNotFound;
1553912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return FindEntry(key, Smi::cast(hash)->value());
1554012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
1554112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1554212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1554312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgtemplate <class Derived, class Iterator, int entrysize>
155444ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgint OrderedHashTable<Derived, Iterator, entrysize>::AddEntry(int hash) {
15545e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsObsolete());
155466a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
155474ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  int entry = UsedCapacity();
155488f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int bucket = HashToBucket(hash);
155498f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int index = EntryToIndex(entry);
155508f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Object* chain_entry = get(kHashTableStartIndex + bucket);
155518f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  set(kHashTableStartIndex + bucket, Smi::FromInt(entry));
155528f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  set(index + kChainOffset, chain_entry);
155538f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  SetNumberOfElements(NumberOfElements() + 1);
155548f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  return index;
155558f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org}
155568f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
155578f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
155584ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate<class Derived, class Iterator, int entrysize>
155594ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgvoid OrderedHashTable<Derived, Iterator, entrysize>::RemoveEntry(int entry) {
15560e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsObsolete());
155616a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
155628f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int index = EntryToIndex(entry);
155638f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  for (int i = 0; i < entrysize; ++i) {
155648f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    set_the_hole(index + i);
155658f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  }
155668f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  SetNumberOfElements(NumberOfElements() - 1);
155678f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
155688f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org}
155698f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
155708f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
155714ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate Handle<OrderedHashSet>
155724ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgOrderedHashTable<OrderedHashSet, JSSetIterator, 1>::Allocate(
155734ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    Isolate* isolate, int capacity, PretenureFlag pretenure);
155744ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
155754ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate Handle<OrderedHashSet>
155764ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgOrderedHashTable<OrderedHashSet, JSSetIterator, 1>::EnsureGrowable(
155774ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    Handle<OrderedHashSet> table);
155784ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
155794ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate Handle<OrderedHashSet>
155804ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgOrderedHashTable<OrderedHashSet, JSSetIterator, 1>::Shrink(
155814ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    Handle<OrderedHashSet> table);
155824ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
155834ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate Handle<OrderedHashSet>
155844ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgOrderedHashTable<OrderedHashSet, JSSetIterator, 1>::Clear(
155854ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    Handle<OrderedHashSet> table);
155864ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
15587196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgtemplate Handle<OrderedHashSet>
15588196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgOrderedHashTable<OrderedHashSet, JSSetIterator, 1>::Remove(
15589196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    Handle<OrderedHashSet> table, Handle<Object> key, bool* was_present);
15590196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
1559112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgtemplate int OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::FindEntry(
1559212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Handle<Object> key, int hash);
1559312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgtemplate int OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::FindEntry(
155943484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    Handle<Object> key);
155954ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
155964ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate int
155974ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgOrderedHashTable<OrderedHashSet, JSSetIterator, 1>::AddEntry(int hash);
155984ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
155994ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate void
156004ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgOrderedHashTable<OrderedHashSet, JSSetIterator, 1>::RemoveEntry(int entry);
156014ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
156024ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
156034ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate Handle<OrderedHashMap>
156044ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgOrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Allocate(
156054ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    Isolate* isolate, int capacity, PretenureFlag pretenure);
156064ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
156074ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate Handle<OrderedHashMap>
156084ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgOrderedHashTable<OrderedHashMap, JSMapIterator, 2>::EnsureGrowable(
156094ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    Handle<OrderedHashMap> table);
156104ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
156114ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate Handle<OrderedHashMap>
156124ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgOrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Shrink(
156134ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    Handle<OrderedHashMap> table);
156144ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
156154ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate Handle<OrderedHashMap>
156164ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgOrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Clear(
156174ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    Handle<OrderedHashMap> table);
156184ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
15619196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgtemplate Handle<OrderedHashMap>
15620196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgOrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Remove(
15621196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    Handle<OrderedHashMap> table, Handle<Object> key, bool* was_present);
15622196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
1562312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgtemplate int OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::FindEntry(
1562412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    Handle<Object> key, int hash);
1562512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgtemplate int OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::FindEntry(
156263484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    Handle<Object> key);
156274ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
156284ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate int
156294ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgOrderedHashTable<OrderedHashMap, JSMapIterator, 2>::AddEntry(int hash);
156304ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
156314ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate void
156324ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgOrderedHashTable<OrderedHashMap, JSMapIterator, 2>::RemoveEntry(int entry);
156338f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
156348f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
156353484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgbool OrderedHashSet::Contains(Handle<Object> key) {
156368f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  return FindEntry(key) != kNotFound;
156378f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org}
156388f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
156398f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
156408f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgHandle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table,
156418f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                                           Handle<Object> key) {
1564212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  int hash = GetOrCreateHash(table->GetIsolate(), key)->value();
1564312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  if (table->FindEntry(key, hash) != kNotFound) return table;
156448f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
156458f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  table = EnsureGrowable(table);
156468f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
1564712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  int index = table->AddEntry(hash);
156488f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  table->set(index, *key);
156498f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  return table;
156508f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org}
156518f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
156528f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
156533484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgObject* OrderedHashMap::Lookup(Handle<Object> key) {
156543484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  DisallowHeapAllocation no_gc;
156558f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  int entry = FindEntry(key);
156568f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  if (entry == kNotFound) return GetHeap()->the_hole_value();
156578f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  return ValueAt(entry);
156588f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org}
156598f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
156608f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
156618f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgHandle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table,
156628f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                                           Handle<Object> key,
156638f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org                                           Handle<Object> value) {
15664e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!key->IsTheHole());
156658f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
1566612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  int hash = GetOrCreateHash(table->GetIsolate(), key)->value();
1566712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  int entry = table->FindEntry(key, hash);
156688f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
156698f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  if (entry != kNotFound) {
156708f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    table->set(table->EntryToIndex(entry) + kValueOffset, *value);
156718f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    return table;
156728f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  }
156738f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
156748f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  table = EnsureGrowable(table);
156758f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
1567612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  int index = table->AddEntry(hash);
156778f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  table->set(index, *key);
156788f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  table->set(index + kValueOffset, *value);
156798f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  return table;
156808f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org}
156818f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
156828f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org
156834ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgtemplate<class Derived, class TableType>
156846a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.orgvoid OrderedHashTableIterator<Derived, TableType>::Transition() {
1568547390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  DisallowHeapAllocation no_allocation;
1568647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  TableType* table = TableType::cast(this->table());
156876a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  if (!table->IsObsolete()) return;
156884ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
156896a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  int index = Smi::cast(this->index())->value();
156906a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  while (table->IsObsolete()) {
1569147390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org    TableType* next_table = table->NextTable();
156924ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
156936a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    if (index > 0) {
156946a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      int nod = table->NumberOfDeletedElements();
156954ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
156966a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      // When we clear the table we set the number of deleted elements to -1.
156976a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      if (nod == -1) {
156986a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org        index = 0;
156996a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      } else {
157006a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org        int old_index = index;
157016a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org        for (int i = 0; i < nod; ++i) {
157026a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org          int removed_index = table->RemovedIndexAt(i);
157036a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org          if (removed_index >= old_index) break;
157046a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org          --index;
157056a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org        }
157066a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      }
157074ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org    }
157086a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
157096a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    table = next_table;
157104ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  }
157114ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1571247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  set_table(table);
157136a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  set_index(Smi::FromInt(index));
157144ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org}
157154ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
157164ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1571747390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgtemplate<class Derived, class TableType>
1571847390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgbool OrderedHashTableIterator<Derived, TableType>::HasMore() {
1571947390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  DisallowHeapAllocation no_allocation;
1572047390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  if (this->table()->IsUndefined()) return false;
157216a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
1572247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  Transition();
157234ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1572447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  TableType* table = TableType::cast(this->table());
1572547390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  int index = Smi::cast(this->index())->value();
1572647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  int used_capacity = table->UsedCapacity();
157274ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1572847390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  while (index < used_capacity && table->KeyAt(index)->IsTheHole()) {
1572947390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org    index++;
1573047390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  }
157316a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
1573247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  set_index(Smi::FromInt(index));
157334ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1573447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  if (index < used_capacity) return true;
157354ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1573647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  set_table(GetHeap()->undefined_value());
1573747390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  return false;
1573847390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org}
157394ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
157404ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1574147390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgtemplate<class Derived, class TableType>
1574247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgSmi* OrderedHashTableIterator<Derived, TableType>::Next(JSArray* value_array) {
1574347390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  DisallowHeapAllocation no_allocation;
1574447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  if (HasMore()) {
1574547390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org    FixedArray* array = FixedArray::cast(value_array->elements());
1574647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org    static_cast<Derived*>(this)->PopulateValueArray(array);
1574747390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org    MoveNext();
157485e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    return Smi::cast(kind());
157494ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org  }
1575047390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  return Smi::FromInt(0);
157514ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org}
157524ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
157534ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1575447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgtemplate Smi*
1575547390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgOrderedHashTableIterator<JSSetIterator, OrderedHashSet>::Next(
1575647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org    JSArray* value_array);
157574ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1575847390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgtemplate bool
1575947390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgOrderedHashTableIterator<JSSetIterator, OrderedHashSet>::HasMore();
157604ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1576147390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgtemplate void
1576247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgOrderedHashTableIterator<JSSetIterator, OrderedHashSet>::MoveNext();
157634ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1576447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgtemplate Object*
1576547390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgOrderedHashTableIterator<JSSetIterator, OrderedHashSet>::CurrentKey();
157664ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1576747390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgtemplate void
1576847390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgOrderedHashTableIterator<JSSetIterator, OrderedHashSet>::Transition();
157694ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
157704ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
1577147390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgtemplate Smi*
1577247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgOrderedHashTableIterator<JSMapIterator, OrderedHashMap>::Next(
1577347390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org    JSArray* value_array);
1577447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org
1577547390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgtemplate bool
1577647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgOrderedHashTableIterator<JSMapIterator, OrderedHashMap>::HasMore();
1577747390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org
1577847390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgtemplate void
1577947390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgOrderedHashTableIterator<JSMapIterator, OrderedHashMap>::MoveNext();
1578047390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org
1578147390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgtemplate Object*
1578247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgOrderedHashTableIterator<JSMapIterator, OrderedHashMap>::CurrentKey();
1578347390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org
1578447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgtemplate void
1578547390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.orgOrderedHashTableIterator<JSMapIterator, OrderedHashMap>::Transition();
157864ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
157874ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org
15788750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgDeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator(
15789750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    DeclaredAccessorDescriptor* descriptor)
15790750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    : array_(descriptor->serialized_data()->GetDataStartAddress()),
15791750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      length_(descriptor->serialized_data()->length()),
15792750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      offset_(0) {
15793750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
15794750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
15795750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
15796750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgconst DeclaredAccessorDescriptorData*
15797750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  DeclaredAccessorDescriptorIterator::Next() {
15798e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(offset_ < length_);
15799750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  uint8_t* ptr = &array_[offset_];
15800e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(reinterpret_cast<uintptr_t>(ptr) % sizeof(uintptr_t) == 0);
15801750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  const DeclaredAccessorDescriptorData* data =
15802750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      reinterpret_cast<const DeclaredAccessorDescriptorData*>(ptr);
15803750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  offset_ += sizeof(*data);
15804e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(offset_ <= length_);
15805750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return data;
15806750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
15807750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
15808750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
15809750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgHandle<DeclaredAccessorDescriptor> DeclaredAccessorDescriptor::Create(
15810750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Isolate* isolate,
15811750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    const DeclaredAccessorDescriptorData& descriptor,
15812750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Handle<DeclaredAccessorDescriptor> previous) {
15813750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  int previous_length =
15814750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      previous.is_null() ? 0 : previous->serialized_data()->length();
15815750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  int length = sizeof(descriptor) + previous_length;
15816750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Handle<ByteArray> serialized_descriptor =
15817750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      isolate->factory()->NewByteArray(length);
15818750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Handle<DeclaredAccessorDescriptor> value =
15819750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      isolate->factory()->NewDeclaredAccessorDescriptor();
15820750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  value->set_serialized_data(*serialized_descriptor);
15821750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Copy in the data.
15822750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  {
1582379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_allocation;
15824750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    uint8_t* array = serialized_descriptor->GetDataStartAddress();
15825750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (previous_length != 0) {
15826750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      uint8_t* previous_array =
15827750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org          previous->serialized_data()->GetDataStartAddress();
15828d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      MemCopy(array, previous_array, previous_length);
15829750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      array += previous_length;
15830750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    }
15831e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(reinterpret_cast<uintptr_t>(array) % sizeof(uintptr_t) == 0);
15832750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    DeclaredAccessorDescriptorData* data =
15833750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org        reinterpret_cast<DeclaredAccessorDescriptorData*>(array);
15834750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    *data = descriptor;
15835750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
15836750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return value;
15837750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
15838750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
15839750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1584043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Check if there is a break point at this code position.
1584143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool DebugInfo::HasBreakPoint(int code_position) {
1584243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the break point info object for this code position.
1584343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* break_point_info = GetBreakPointInfo(code_position);
1584443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1584543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If there is no break point info object or no break points in the break
1584643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // point info object there is no break point at this code position.
1584743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (break_point_info->IsUndefined()) return false;
1584843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0;
1584943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1585043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1585143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1585243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Get the break point info object for this code position.
1585343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenObject* DebugInfo::GetBreakPointInfo(int code_position) {
1585443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Find the index of the break point info object for this code position.
1585543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index = GetBreakPointInfoIndex(code_position);
1585643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1585743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return the break point info object if any.
15858c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (index == kNoBreakPointInfo) return GetHeap()->undefined_value();
1585943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return BreakPointInfo::cast(break_points()->get(index));
1586043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1586143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1586243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1586343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Clear a break point at the specified code position.
1586443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info,
1586543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                int code_position,
1586643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                Handle<Object> break_point_object) {
1586709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position),
158683d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                                  debug_info->GetIsolate());
1586943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (break_point_info->IsUndefined()) return;
1587043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  BreakPointInfo::ClearBreakPoint(
1587143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Handle<BreakPointInfo>::cast(break_point_info),
1587243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break_point_object);
1587343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1587443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1587543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1587643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info,
1587743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                              int code_position,
1587843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                              int source_position,
1587943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                              int statement_position,
1588043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                              Handle<Object> break_point_object) {
158813d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  Isolate* isolate = debug_info->GetIsolate();
1588209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position),
1588309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org                                  isolate);
1588443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!break_point_info->IsUndefined()) {
1588543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    BreakPointInfo::SetBreakPoint(
1588643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Handle<BreakPointInfo>::cast(break_point_info),
1588743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        break_point_object);
1588843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
1588943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1589043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1589143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Adding a new break point for a code position which did not have any
1589243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // break points before. Try to find a free slot.
1589343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int index = kNoBreakPointInfo;
1589443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < debug_info->break_points()->length(); i++) {
1589543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (debug_info->break_points()->get(i)->IsUndefined()) {
1589643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      index = i;
1589743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      break;
1589843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1589943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1590043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (index == kNoBreakPointInfo) {
1590143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // No free slot - extend break point info array.
1590243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<FixedArray> old_break_points =
1590343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        Handle<FixedArray>(FixedArray::cast(debug_info->break_points()));
1590443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<FixedArray> new_break_points =
15905ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        isolate->factory()->NewFixedArray(
15906ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org            old_break_points->length() +
159078d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            DebugInfo::kEstimatedNofBreakPointsInFunction);
159084a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
159094a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org    debug_info->set_break_points(*new_break_points);
1591043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (int i = 0; i < old_break_points->length(); i++) {
1591143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      new_break_points->set(i, old_break_points->get(i));
1591243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1591343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    index = old_break_points->length();
1591443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
15915e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index != kNoBreakPointInfo);
1591643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1591743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Allocate new BreakPointInfo object and set the break point.
15918ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<BreakPointInfo> new_break_point_info = Handle<BreakPointInfo>::cast(
15919ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewStruct(BREAK_POINT_INFO_TYPE));
1592043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  new_break_point_info->set_code_position(Smi::FromInt(code_position));
1592143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  new_break_point_info->set_source_position(Smi::FromInt(source_position));
1592243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  new_break_point_info->
1592343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      set_statement_position(Smi::FromInt(statement_position));
15924ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  new_break_point_info->set_break_point_objects(
15925ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->heap()->undefined_value());
1592643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object);
1592743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  debug_info->break_points()->set(index, *new_break_point_info);
1592843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1592943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1593043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1593143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Get the break point objects for a code position.
1593243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenObject* DebugInfo::GetBreakPointObjects(int code_position) {
1593343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* break_point_info = GetBreakPointInfo(code_position);
1593443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (break_point_info->IsUndefined()) {
15935c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return GetHeap()->undefined_value();
1593643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1593743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return BreakPointInfo::cast(break_point_info)->break_point_objects();
1593843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1593943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1594043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1594143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Get the total number of break points.
1594243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint DebugInfo::GetBreakPointCount() {
1594343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (break_points()->IsUndefined()) return 0;
1594443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int count = 0;
1594543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < break_points()->length(); i++) {
1594643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!break_points()->get(i)->IsUndefined()) {
1594743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      BreakPointInfo* break_point_info =
1594843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          BreakPointInfo::cast(break_points()->get(i));
1594943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      count += break_point_info->GetBreakPointCount();
1595043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1595143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1595243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return count;
1595343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1595443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1595543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1595643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenObject* DebugInfo::FindBreakPointInfo(Handle<DebugInfo> debug_info,
1595743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                      Handle<Object> break_point_object) {
15958c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Heap* heap = debug_info->GetHeap();
15959ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (debug_info->break_points()->IsUndefined()) return heap->undefined_value();
1596043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < debug_info->break_points()->length(); i++) {
1596143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!debug_info->break_points()->get(i)->IsUndefined()) {
1596243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Handle<BreakPointInfo> break_point_info =
1596343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          Handle<BreakPointInfo>(BreakPointInfo::cast(
1596443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen              debug_info->break_points()->get(i)));
1596543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (BreakPointInfo::HasBreakPointObject(break_point_info,
1596643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                              break_point_object)) {
1596743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        return *break_point_info;
1596843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1596943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1597043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
15971ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return heap->undefined_value();
1597243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1597343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1597443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1597543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Find the index of the break point info object for the specified code
1597643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// position.
1597743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint DebugInfo::GetBreakPointInfoIndex(int code_position) {
1597843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (break_points()->IsUndefined()) return kNoBreakPointInfo;
1597943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < break_points()->length(); i++) {
1598043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!break_points()->get(i)->IsUndefined()) {
1598143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      BreakPointInfo* break_point_info =
1598243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          BreakPointInfo::cast(break_points()->get(i));
1598343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (break_point_info->code_position()->value() == code_position) {
1598443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        return i;
1598543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
1598643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1598743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1598843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return kNoBreakPointInfo;
1598943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1599043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1599143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1599243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Remove the specified break point object.
1599343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info,
1599443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                     Handle<Object> break_point_object) {
159953d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  Isolate* isolate = break_point_info->GetIsolate();
1599643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If there are no break points just ignore.
1599743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (break_point_info->break_point_objects()->IsUndefined()) return;
1599843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If there is a single break point clear it if it is the same.
1599943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!break_point_info->break_point_objects()->IsFixedArray()) {
1600043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (break_point_info->break_point_objects() == *break_point_object) {
16001ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      break_point_info->set_break_point_objects(
16002ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          isolate->heap()->undefined_value());
1600343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1600443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
1600543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1600643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If there are multiple break points shrink the array
16007e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(break_point_info->break_point_objects()->IsFixedArray());
1600843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<FixedArray> old_array =
1600943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Handle<FixedArray>(
1601043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          FixedArray::cast(break_point_info->break_point_objects()));
1601143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<FixedArray> new_array =
16012ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->factory()->NewFixedArray(old_array->length() - 1);
1601343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int found_count = 0;
1601443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < old_array->length(); i++) {
1601543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (old_array->get(i) == *break_point_object) {
16016e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(found_count == 0);
1601743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      found_count++;
1601843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
1601943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      new_array->set(i - found_count, old_array->get(i));
1602043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1602143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1602243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the break point was found in the list change it.
1602343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (found_count > 0) break_point_info->set_break_point_objects(*new_array);
1602443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1602543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1602643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1602743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Add the specified break point object.
1602843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid BreakPointInfo::SetBreakPoint(Handle<BreakPointInfo> break_point_info,
1602943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                   Handle<Object> break_point_object) {
16030d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Isolate* isolate = break_point_info->GetIsolate();
16031d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1603243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If there was no break point objects before just set it.
1603343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (break_point_info->break_point_objects()->IsUndefined()) {
1603443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    break_point_info->set_break_point_objects(*break_point_object);
1603543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
1603643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1603743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the break point object is the same as before just ignore.
1603843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (break_point_info->break_point_objects() == *break_point_object) return;
1603943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If there was one break point object before replace with array.
1604043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!break_point_info->break_point_objects()->IsFixedArray()) {
16041d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    Handle<FixedArray> array = isolate->factory()->NewFixedArray(2);
1604243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    array->set(0, break_point_info->break_point_objects());
1604343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    array->set(1, *break_point_object);
1604443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    break_point_info->set_break_point_objects(*array);
1604543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return;
1604643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1604743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If there was more than one break point before extend array.
1604843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<FixedArray> old_array =
1604943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Handle<FixedArray>(
1605043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen          FixedArray::cast(break_point_info->break_point_objects()));
1605143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<FixedArray> new_array =
16052d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      isolate->factory()->NewFixedArray(old_array->length() + 1);
1605343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < old_array->length(); i++) {
1605443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // If the break point was there before just ignore.
1605543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (old_array->get(i) == *break_point_object) return;
1605643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    new_array->set(i, old_array->get(i));
1605743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1605843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Add the new break point.
1605943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  new_array->set(old_array->length(), *break_point_object);
1606043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  break_point_info->set_break_point_objects(*new_array);
1606143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1606243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1606343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1606443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool BreakPointInfo::HasBreakPointObject(
1606543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<BreakPointInfo> break_point_info,
1606643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Handle<Object> break_point_object) {
1606743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // No break point.
1606843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (break_point_info->break_point_objects()->IsUndefined()) return false;
160697c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  // Single break point.
1607043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!break_point_info->break_point_objects()->IsFixedArray()) {
1607143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return break_point_info->break_point_objects() == *break_point_object;
1607243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1607343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Multiple break points.
1607443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  FixedArray* array = FixedArray::cast(break_point_info->break_point_objects());
1607543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < array->length(); i++) {
1607643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (array->get(i) == *break_point_object) {
1607743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      return true;
1607843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1607943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1608043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return false;
1608143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1608243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1608343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1608443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Get the number of break points.
1608543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint BreakPointInfo::GetBreakPointCount() {
1608643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // No break point.
1608743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (break_point_objects()->IsUndefined()) return 0;
160887c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  // Single break point.
1608943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!break_point_objects()->IsFixedArray()) return 1;
1609043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Multiple break points.
1609143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return FixedArray::cast(break_point_objects())->length();
1609243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1609343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1609486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
16095212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgObject* JSDate::GetField(Object* object, Smi* index) {
160964efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  return JSDate::cast(object)->DoGetField(
160974efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      static_cast<FieldIndex>(index->value()));
160984efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org}
160994efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161004efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161014efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.orgObject* JSDate::DoGetField(FieldIndex index) {
16102e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index != kDateValue);
161034efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161044efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  DateCache* date_cache = GetIsolate()->date_cache();
161054efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161064efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  if (index < kFirstUncachedField) {
161074efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    Object* stamp = cache_stamp();
161084efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    if (stamp != date_cache->stamp() && stamp->IsSmi()) {
161094efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      // Since the stamp is not NaN, the value is also not NaN.
161104efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      int64_t local_time_ms =
161114efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org          date_cache->ToLocal(static_cast<int64_t>(value()->Number()));
16112fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      SetCachedFields(local_time_ms, date_cache);
161134efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    }
161144efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    switch (index) {
161154efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      case kYear: return year();
161164efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      case kMonth: return month();
161174efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      case kDay: return day();
161184efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      case kWeekday: return weekday();
161194efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      case kHour: return hour();
161204efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      case kMinute: return min();
161214efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      case kSecond: return sec();
161224efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org      default: UNREACHABLE();
161234efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    }
161244efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  }
161254efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161264efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  if (index >= kFirstUTCField) {
161274efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    return GetUTCField(index, value()->Number(), date_cache);
161284efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  }
161294efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161304efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  double time = value()->Number();
1613177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(time)) return GetIsolate()->heap()->nan_value();
161324efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161334efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int64_t local_time_ms = date_cache->ToLocal(static_cast<int64_t>(time));
161344efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int days = DateCache::DaysFromTime(local_time_ms);
161354efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161364efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  if (index == kDays) return Smi::FromInt(days);
161374efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161384efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
161394efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  if (index == kMillisecond) return Smi::FromInt(time_in_day_ms % 1000);
16140e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index == kTimeInDay);
161414efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  return Smi::FromInt(time_in_day_ms);
161424efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org}
161434efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161444efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161454efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.orgObject* JSDate::GetUTCField(FieldIndex index,
161464efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org                            double value,
161474efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org                            DateCache* date_cache) {
16148e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(index >= kFirstUTCField);
161494efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
1615077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(value)) return GetIsolate()->heap()->nan_value();
161514efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161524efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int64_t time_ms = static_cast<int64_t>(value);
161534efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161544efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  if (index == kTimezoneOffset) {
161554efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    return Smi::FromInt(date_cache->TimezoneOffset(time_ms));
161564efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  }
161574efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161584efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int days = DateCache::DaysFromTime(time_ms);
161594efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161604efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  if (index == kWeekdayUTC) return Smi::FromInt(date_cache->Weekday(days));
161614efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161624efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  if (index <= kDayUTC) {
161634efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    int year, month, day;
161644efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    date_cache->YearMonthDayFromDays(days, &year, &month, &day);
161654efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    if (index == kYearUTC) return Smi::FromInt(year);
161664efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    if (index == kMonthUTC) return Smi::FromInt(month);
16167e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(index == kDayUTC);
161684efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    return Smi::FromInt(day);
161694efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  }
161704efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161714efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int time_in_day_ms = DateCache::TimeInDay(time_ms, days);
161724efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  switch (index) {
161734efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    case kHourUTC: return Smi::FromInt(time_in_day_ms / (60 * 60 * 1000));
161744efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    case kMinuteUTC: return Smi::FromInt((time_in_day_ms / (60 * 1000)) % 60);
161754efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    case kSecondUTC: return Smi::FromInt((time_in_day_ms / 1000) % 60);
161764efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    case kMillisecondUTC: return Smi::FromInt(time_in_day_ms % 1000);
161774efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    case kDaysUTC: return Smi::FromInt(days);
161784efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    case kTimeInDayUTC: return Smi::FromInt(time_in_day_ms);
161794efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    default: UNREACHABLE();
161804efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  }
161814efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161824efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  UNREACHABLE();
161834efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  return NULL;
161844efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org}
161854efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161864efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
161874efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.orgvoid JSDate::SetValue(Object* value, bool is_value_nan) {
161884efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  set_value(value);
161894efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  if (is_value_nan) {
161904efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    HeapNumber* nan = GetIsolate()->heap()->nan_value();
161914efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    set_cache_stamp(nan, SKIP_WRITE_BARRIER);
161924efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    set_year(nan, SKIP_WRITE_BARRIER);
161934efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    set_month(nan, SKIP_WRITE_BARRIER);
161944efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    set_day(nan, SKIP_WRITE_BARRIER);
161954efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    set_hour(nan, SKIP_WRITE_BARRIER);
161964efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    set_min(nan, SKIP_WRITE_BARRIER);
161974efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    set_sec(nan, SKIP_WRITE_BARRIER);
161984efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    set_weekday(nan, SKIP_WRITE_BARRIER);
161994efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  } else {
162004efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org    set_cache_stamp(Smi::FromInt(DateCache::kInvalidStamp), SKIP_WRITE_BARRIER);
162014efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  }
162024efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org}
162034efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
162044efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
16205fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.orgvoid JSDate::SetCachedFields(int64_t local_time_ms, DateCache* date_cache) {
162064efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int days = DateCache::DaysFromTime(local_time_ms);
162074efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
162084efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int year, month, day;
162094efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  date_cache->YearMonthDayFromDays(days, &year, &month, &day);
162104efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int weekday = date_cache->Weekday(days);
162114efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int hour = time_in_day_ms / (60 * 60 * 1000);
162124efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int min = (time_in_day_ms / (60 * 1000)) % 60;
162134efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  int sec = (time_in_day_ms / 1000) % 60;
162144efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  set_cache_stamp(date_cache->stamp());
162154efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
162164efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
162174efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
162184efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
162194efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
162204efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
162214efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
162224efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org}
162234efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
162241fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
162251fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgvoid JSArrayBuffer::Neuter() {
16226e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_external());
162271fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  set_backing_store(NULL);
162281fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  set_byte_length(Smi::FromInt(0));
162291fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org}
162301fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
162311fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
162321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid JSArrayBufferView::NeuterView() {
162331fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  set_byte_offset(Smi::FromInt(0));
162341fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  set_byte_length(Smi::FromInt(0));
162351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
162361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
162371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
162381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid JSDataView::Neuter() {
162391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  NeuterView();
162401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
162411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
162421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
162431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid JSTypedArray::Neuter() {
162441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  NeuterView();
162451fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  set_length(Smi::FromInt(0));
162461fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  set_elements(GetHeap()->EmptyExternalArrayForMap(map()));
162471fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org}
162481fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
1624941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
16250895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgstatic ElementsKind FixedToExternalElementsKind(ElementsKind elements_kind) {
16251895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  switch (elements_kind) {
16252895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                       \
16253895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    case TYPE##_ELEMENTS: return EXTERNAL_##TYPE##_ELEMENTS;
16254895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
16255895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    TYPED_ARRAYS(TYPED_ARRAY_CASE)
16256895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org#undef TYPED_ARRAY_CASE
16257895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
16258895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    default:
16259895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      UNREACHABLE();
16260895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      return FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND;
16261895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  }
16262895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org}
16263895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
16264895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
16265895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgHandle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer(
16266895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    Handle<JSTypedArray> typed_array) {
16267895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
16268895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Handle<Map> map(typed_array->map());
16269895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Isolate* isolate = typed_array->GetIsolate();
16270895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
16271e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsFixedTypedArrayElementsKind(map->elements_kind()));
16272895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
16273af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  Handle<Map> new_map = Map::TransitionElementsTo(
16274af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org          map,
16275af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org          FixedToExternalElementsKind(map->elements_kind()));
16276af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org
16277895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
16278895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Handle<FixedTypedArrayBase> fixed_typed_array(
16279895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      FixedTypedArrayBase::cast(typed_array->elements()));
16280895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Runtime::SetupArrayBufferAllocatingData(isolate, buffer,
16281895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      fixed_typed_array->DataSize(), false);
16282895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  memcpy(buffer->backing_store(),
16283895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org         fixed_typed_array->DataPtr(),
16284895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org         fixed_typed_array->DataSize());
16285895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Handle<ExternalArray> new_elements =
16286895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      isolate->factory()->NewExternalArray(
16287895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org          fixed_typed_array->length(), typed_array->type(),
16288895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org          static_cast<uint8_t*>(buffer->backing_store()));
16289895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
16290895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  buffer->set_weak_first_view(*typed_array);
16291e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(typed_array->weak_next() == isolate->heap()->undefined_value());
16292895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  typed_array->set_buffer(*buffer);
1629363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  JSObject::SetMapAndElements(typed_array, new_map, new_elements);
16294895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
16295895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  return buffer;
16296895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org}
16297895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
16298895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
16299895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgHandle<JSArrayBuffer> JSTypedArray::GetBuffer() {
16300895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Handle<Object> result(buffer(), GetIsolate());
16301895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  if (*result != Smi::FromInt(0)) {
16302e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsExternalArrayElementsKind(map()->elements_kind()));
16303895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    return Handle<JSArrayBuffer>::cast(result);
16304895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  }
16305895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Handle<JSTypedArray> self(this);
16306895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  return MaterializeArrayBuffer(self);
16307895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org}
16308895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
16309895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
163106d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgHeapType* PropertyCell::type() {
163116d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  return static_cast<HeapType*>(type_raw());
1631241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
1631341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
1631441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
163156d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgvoid PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) {
16316e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsPropertyCell());
1631741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  set_type_raw(type, ignored);
1631841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
1631941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
1632041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
163216d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgHandle<HeapType> PropertyCell::UpdatedType(Handle<PropertyCell> cell,
163226d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org                                           Handle<Object> value) {
16323e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  Isolate* isolate = cell->GetIsolate();
163246d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Handle<HeapType> old_type(cell->type(), isolate);
1632593720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  Handle<HeapType> new_type = HeapType::Constant(value, isolate);
16326e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1632793720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  if (new_type->Is(old_type)) return old_type;
16328e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
16329e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  cell->dependent_code()->DeoptimizeDependentCodeGroup(
16330e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      isolate, DependentCode::kPropertyCellChangedGroup);
16331e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
163326d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  if (old_type->Is(HeapType::None()) || old_type->Is(HeapType::Undefined())) {
16333db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org    return new_type;
16334e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  }
16335e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
163366d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  return HeapType::Any(isolate);
16337e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org}
16338e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
16339e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
16340528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid PropertyCell::SetValueInferType(Handle<PropertyCell> cell,
1634171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org                                     Handle<Object> value) {
1634271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  cell->set_value(*value);
163436d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  if (!HeapType::Any()->Is(cell->type())) {
163446d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    Handle<HeapType> new_type = UpdatedType(cell, value);
16345db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org    cell->set_type(*new_type);
16346e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  }
16347e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org}
16348e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
16349e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
16350e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org// static
16351e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgvoid PropertyCell::AddDependentCompilationInfo(Handle<PropertyCell> cell,
16352e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                                               CompilationInfo* info) {
163531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<DependentCode> codes =
16354e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      DependentCode::Insert(handle(cell->dependent_code(), info->isolate()),
16355e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                            DependentCode::kPropertyCellChangedGroup,
163561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                            info->object_wrapper());
16357e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes);
163581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
16359e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      cell, info->zone());
163601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
163611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1636243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
16363